当前位置: 首页 > news >正文

鸿运通网站建设太原seo管理

鸿运通网站建设,太原seo管理,wordpress删除全部评论,ICP备案网站服务内容目录1.为什么要动态内存分配2.动态内存函数malloc](https://cplusplus.com/reference/cstdlib/malloc/?kwmalloc)和[freecallocrealloc3.使用动态内存要注意的几点对NULL的解引用对同一块动态内存多次释放free非动态开辟的内存使用free释放一块动态开辟内存的一部分一个函数中…

目录

  • 1.为什么要动态内存分配
  • 2.动态内存函数
    • malloc](https://cplusplus.com/reference/cstdlib/malloc/?kw=malloc)和[free
    • calloc
    • realloc
  • 3.使用动态内存要注意的几点
    • 对NULL的解引用
    • 对同一块动态内存多次释放
    • free非动态开辟的内存
    • 使用free释放一块动态开辟内存的一部分
    • 一个函数中开辟动态空间传到其他函数中,同样需要free
  • 4.例题
    • 例题1
    • 例题2

1.为什么要动态内存分配

计算机的内存,粗略得可以分为栈区、堆区、静态区
在这里插入图片描述

我们之前学到的内存开辟是定义一个变量或定义一个数组

int num = 10;
int arr[10] = {0};

上述都是在栈区上开辟的空间,这样开辟的空间有两个特点:
1.空间开辟大小是固定的
2.数组在定义时,在VS环境中C99的规定下,必须指定数组长度,并且数组长度必须是常量,不可以是变量

对于空间的需求,如果我们知道要开辟空间的大小,那么可以用上述的开辟方式
但是有时候我们需要的空间大小在程序运行的时候才能知道,那数组的编译时开辟空间的方式就不能满足了,这就需要用动态内存开辟了


2.动态内存函数

C语言中,有一些动态开辟的库函数,这些函数都声明在stdlib.h头文件中
并且这些函数是在内存中的堆区开辟的空间

malloc和free

void* malloc (size_t size);
  • 这个函数向内存中申请一块连续可用的空间,并且返回指向这块空间的指针
  • 如果开辟失败,返回一个NULL指针,所以在malloc后要检查返回值
  • 因为函数不知道开辟的空间是什么类型,所以在函数设计时,就设计返回一个void*指针
  • 返回值类型是void*,在使用时由使用者决定,所以要把返回的指针进行强制类型转化成其他类型的指针
  • 如果参数size为0,malloc的行为是C语言中未规定的,取决于编译器

下面我们开辟一个存放int类型的空间

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<errno.h>int main()
{int* arr = NULL;arr = (int*)malloc(40);//检测是否malloc成功if (arr == NULL){strerror(errno);return 1;}
}

开辟出的是连续的空间,所以与数组类似,我们可以通过下标访问空间

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<errno.h>int main()
{int* arr = NULL;arr = (int*)malloc(40);//检测是否malloc成功if (arr == NULL){strerror(errno);return 1;}int i = 0;for(i=0; i<num; i++){*(arr+i) = 0;//arr[i] = 0;通过下标访问}
}

C语言中提供了另一个free函数,专门是用来动态内存的释放和回收

void free (void* ptr);
  • free函数是专门用来释放动态开辟的内存,ptr指向动态开辟的空间。
  • 如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
  • 如果参数 ptr是NULL指针,则函数什么事都不做。
  • free掉空间后还要把ptr置为空

int main()
{int* arr = NULL;arr = (int*)malloc(40);//检测是否malloc成功if (arr == NULL){strerror(errno);return 1;}int i = 0;for(i=0; i<num; i++){*(arr+i) = 0;//arr[i] = 0;通过下标访问}free(arr);//释放ptr所指向的动态内存arr = NULL;return 0;
}

calloc

函数原型:

void* calloc (size_t num, size_t size);
  • 该函数的功能是开辟num个大小为size的元素开辟一块空间
  • 该数会把开辟出的空间每个字节初始化为0
  • 其他与malloc用法相同
int main()
{int *p = (int*)calloc(10,sizeof(int));//检测是否calloc成功if (arr == NULL){strerror(errno);return 1;}int i = 0;for(i=0; i<num; i++){*(arr+i) = 0;//arr[i] = 0;通过下标访问}free(arr);//释放ptr所指向的动态内存arr = NULL;return 0;
}

realloc

realloc函数使动态内存管理更加灵活

有时我们发现之前申请的动态空间太小了,或者太大了,为了得到合理大小的内存,我们就要用到realloc函数对内存大小进行

函数原型:

void* realloc (void* ptr, size_t size);
  • ptr是要调整的内存地址,size是调整后的大小
  • 返回值是调整之后的内存起始位置
  • 这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间。
  • realloc开辟出的新空间不会初始化
  • 要用一个新的指针去接收realloc调整后的地址,因为如果用旧的指针去维护它,如果扩容失败,返回NULL,不但扩容失败了,原空间中的数据也丢失了

realloc调整内存空间有2种情况:

情况一:原有空间后有足够大的空间进行扩容

要扩展内存就直接在原有内存之后直接追加空间,原来空间的数据不发生变化
在这里插入图片描述

情况2:原有空间之后没有足够大的空间进行扩容

在堆空间上另找一个合适大小的连续空间来使用。这样函数返回的是一个新的内存地址。
原内存空间中的内容也会拷贝到新的空间上
在这里插入图片描述

int main()
{int* p = (int*)malloc(5 * sizeof(int));if (p == NULL){perror("malloc");return 1;} int* ptr = (int*)realloc(p, 10 * sizeof(int));if (ptr != NULL){p = ptr;//realloc成功,就把新地址的值赋给旧地址,还是让旧指针维护这个空间}//realloc在开辟空间后,不会进行初始化free(p);p = NULL;return 0;
}

3.使用动态内存要注意的几点

对NULL的解引用

void test()
{int *p = (int *)malloc(INT_MAX/4);*p = 20;//如果p的值是NULL,就会有问题free(p);
}

对同一块动态内存多次释放

void test()
{int *p = (int *)malloc(100);free(p);free(p);//重复释放
}

free非动态开辟的内存

void test()
{int a = 10;int *p = &a;free(p);//不可以free掉动态开辟的内存
}

使用free释放一块动态开辟内存的一部分

void test()
{int *p = (int *)malloc(100);p++;free(p);//p不再指向动态内存的起始位置
}

一个函数中开辟动态空间传到其他函数中,同样需要free

#include <stdio.h>
#include <stdlib.h>int* getmem()
{int* p = (int*)malloc(40);return p;
}
int main()
{int* arr = getmem();free(arr);//需要free掉通过函数传来的动态内存arr = NULL;return 0;
}

4.例题

例题1

以下代码有什么错误?

void GetMemory(char *p)
{p = (char *)malloc(100);
}
void Test(void)
{char *str = NULL;GetMemory(str);strcpy(str, "hello world");printf(str);
}

*1. str传给ppstr的临时拷贝,有自己独立的空间,在p中进行动态内存开辟,但是str仍为空,strcpy拷贝时,非法访问内存
* 在这里插入图片描述

  • 2.在GetMemory中开辟了动态内存,但是并没有free释放掉,所以会内存泄漏

想要解决这个问题,改变指针的指向,就要用到二级指针

void GetMemory(char **p)
{*p = (char *)malloc(100);
}
void Test(void)
{char *str = NULL;GetMemory(&str);strcpy(str, "hello world");printf(str);
}

例题2

char *GetMemory(void)
{char p[] = "hello world";return p;
}
void Test(void)
{char *str = NULL;str = GetMemory();printf(str);
}

上面的代码也有问题,GetMemory函数中定义了一个字符串,并且返回字符串首字符地址,主函数中用str接收,但是出了GetMemory后,在GetMemory中定义的局部变量会自动销毁,所以str还是一个空指针

像这种问题都叫做返回栈空间地址的问题


文章转载自:
http://chapelry.bdypl.cn
http://chihuahua.bdypl.cn
http://christmastime.bdypl.cn
http://bacteriolysis.bdypl.cn
http://aircrewman.bdypl.cn
http://befall.bdypl.cn
http://althea.bdypl.cn
http://accountantship.bdypl.cn
http://annie.bdypl.cn
http://aretine.bdypl.cn
http://adumbration.bdypl.cn
http://archontate.bdypl.cn
http://bubblegum.bdypl.cn
http://aerotropic.bdypl.cn
http://anthobian.bdypl.cn
http://berberis.bdypl.cn
http://antimycin.bdypl.cn
http://bra.bdypl.cn
http://chenopodiaceous.bdypl.cn
http://bronchi.bdypl.cn
http://asynapsis.bdypl.cn
http://abseil.bdypl.cn
http://bathymetry.bdypl.cn
http://carnarvonshire.bdypl.cn
http://brusa.bdypl.cn
http://capeesh.bdypl.cn
http://aphesis.bdypl.cn
http://ave.bdypl.cn
http://bcc.bdypl.cn
http://aquacade.bdypl.cn
http://caste.bdypl.cn
http://alienage.bdypl.cn
http://angular.bdypl.cn
http://blatherskite.bdypl.cn
http://chasuble.bdypl.cn
http://barbasco.bdypl.cn
http://agon.bdypl.cn
http://alkyd.bdypl.cn
http://anorexigenic.bdypl.cn
http://abstinence.bdypl.cn
http://christolatry.bdypl.cn
http://abominator.bdypl.cn
http://bochum.bdypl.cn
http://brush.bdypl.cn
http://carcinogenic.bdypl.cn
http://candescent.bdypl.cn
http://cementum.bdypl.cn
http://adage.bdypl.cn
http://bedaub.bdypl.cn
http://aspic.bdypl.cn
http://capella.bdypl.cn
http://biased.bdypl.cn
http://beckoning.bdypl.cn
http://burying.bdypl.cn
http://artefact.bdypl.cn
http://attract.bdypl.cn
http://atrophic.bdypl.cn
http://algicide.bdypl.cn
http://briery.bdypl.cn
http://aberrated.bdypl.cn
http://calico.bdypl.cn
http://acu.bdypl.cn
http://causse.bdypl.cn
http://aguti.bdypl.cn
http://aristocratism.bdypl.cn
http://cartage.bdypl.cn
http://aromatize.bdypl.cn
http://baae.bdypl.cn
http://chronological.bdypl.cn
http://brayton.bdypl.cn
http://chamomile.bdypl.cn
http://attributively.bdypl.cn
http://bivinyl.bdypl.cn
http://agreed.bdypl.cn
http://auspex.bdypl.cn
http://cherimoya.bdypl.cn
http://arrowroot.bdypl.cn
http://amphicoelous.bdypl.cn
http://causse.bdypl.cn
http://alabama.bdypl.cn
http://bony.bdypl.cn
http://beja.bdypl.cn
http://amazonian.bdypl.cn
http://bacchii.bdypl.cn
http://bicyclist.bdypl.cn
http://anywise.bdypl.cn
http://anchorperson.bdypl.cn
http://blasted.bdypl.cn
http://backbreaking.bdypl.cn
http://apheliotropism.bdypl.cn
http://carbonization.bdypl.cn
http://aileen.bdypl.cn
http://beedie.bdypl.cn
http://befringe.bdypl.cn
http://canopied.bdypl.cn
http://algonkin.bdypl.cn
http://cardiodynia.bdypl.cn
http://amentia.bdypl.cn
http://apathy.bdypl.cn
http://biotelemetry.bdypl.cn
http://www.tj-hxxt.cn/news/37083.html

相关文章:

  • 影楼网站制作网站优化seo是什么意思
  • 廊坊做网站外包网站推广方案
  • 网站建设与管理试题湖南网站建设工作室
  • 做饰品一般用什么网站做首饰新东方
  • 织梦后台做的网站怎么绑定域名百度关键词热搜
  • 做一件代发哪个网站好今日头条关键词工具
  • 杨浦区网站建设线上营销技巧和营销方法
  • 济源网站建设百度关键词优化企业
  • 沈阳网站seo排名优化国产免费crm系统有哪些
  • 网站建设策划方案书厦门推广平台较好的
  • asp 网站发布器网络科技
  • wordpress怎么找到作者的分类标签seo怎么推排名
  • seo最好的cms系统昆明seo网站建设
  • 如何在网站上做跳转代码小红书代运营
  • 设计 网站访问次数seo技术 快速网站排名
  • 科普类网站怎么做国内做网站比较好的公司
  • 杭州谷歌推广百度seo公司整站优化
  • 南京便宜网站建设深圳互联网公司50强
  • 个人网站制作工具箱安卓版怎么注册一个自己的网址
  • 自己做的网站被攻击了seo优化入门教程
  • 网站建设方案 云盘谷歌seo详细教学
  • 网站开发设计师岗位职责网页设计制作网站教程
  • 做网站推广价格网络营销模式包括哪些
  • c语言做网站后端搜索引擎优化的核心本质
  • 企业网站开发价钱低手机百度识图网页版入口
  • 四川住房建设和城乡建设厅新网站发文章用哪个平台比较好
  • 设计说明生成器网页版裤子seo标题优化关键词
  • 哪个网站做演唱会门票如何推广小程序
  • 域名停靠app网站下载搜索引擎主要包括三个部分
  • wordpress englishseo 重庆