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

响应式单页网站模板dw网站建设框架大小设定

响应式单页网站模板,dw网站建设框架大小设定,wordpress 运行效率,江门免费建站公司文章目录 1.为什么要有动态内存分配2.malloc和free2.1 malloc2.2 free 3.calloc和realloc3.1 calloc3.2 realloc 4.常见的动态内存的错误4.1 对NULL指针的解引⽤操作4.2 对动态开辟空间的越界访问4.3 对⾮动态开辟内存使⽤free释放4.4 使⽤free释放⼀块动态开辟内存的⼀部分4.5… 文章目录 1.为什么要有动态内存分配2.malloc和free2.1 malloc2.2 free 3.calloc和realloc3.1 calloc3.2 realloc 4.常见的动态内存的错误4.1 对NULL指针的解引⽤操作4.2 对动态开辟空间的越界访问4.3 对⾮动态开辟内存使⽤free释放4.4 使⽤free释放⼀块动态开辟内存的⼀部分4.5 对同⼀块动态内存多次释放4.6 动态开辟内存忘记释放内存泄漏 5.动态内存经典笔试题分析5.1 题⽬15.2 题⽬25.3 题⽬35.4 题⽬4 6.柔性数组6.1 柔性数组的特点6.2 柔性数组的使⽤6.3 柔性数组的优势 7.总结C/C中程序内存区域划分 1.为什么要有动态内存分配 我们已经掌握的内存开辟方式有 int val 20;//在栈空间上开辟四个字节 char arr[10] {0};//在栈空间上开辟10个字节的连续空间但是上述的开辟空间的方式有两个特点 空间开辟大小是固定的。 数组在申明的时候必须指定数组的长度数组空间一旦确定了大小不能调整 但是对于空间的需求不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道那数组的编译时开辟空间的方式就不能满足了。 C语言引入了动态内存开辟让程序员自己可以申请和释放空间就比较灵活了。 2.malloc和free 2.1 malloc C语言提供了一个动态内存开辟的函数 void* malloc (size_t size);参数 size 是你想要分配的内存块的大小以字节为单位。如果 malloc 成功分配了内存它会返回一个指向分配内存块的指针。如果分配失败比如内存不足它会返回一个空指针 NULL 。 这个函数向内存申请一块连续可用的空间并返回指向这块空间的指针。 如果开辟成功则返回一个指向开辟好空间的指针。 如果开辟失败则返回一个 NULL 指针因此malloc的返回值一定要做检查。 返回值的类型是 void* 所以malloc函数并不知道开辟空间的类型具体在使用的时候使用者自己来决定。 如果参数 size 为0malloc的行为是标准是未定义的取决于编译器。 参数的单位是字节 申请空间成功的话返回这块空间的起始地址。 申请失败的话返回NULL #include stdlib.hint main() {int* p (int*)malloc(10 * sizeof(int));if (p NULL) {//空间开辟失败perror(malloc);return 1;}//可以使用这40个字节int i 0;for (i 0; i 10; i) {*(p i) i 1;}return 0; }2.2 free C语言提供了另外一个函数free专门是用来做动态内存的释放和回收的函数原型如下 void free (void* ptr);free函数用来释放动态开辟的内存。 如果参数 ptr 指向的空间不是动态开辟的那free函数的行为是未定义的。 如果参数 ptr 是NULL指针则函数什么事都不做。 malloc和free都声明在 stdlib.h 头文件中。 举个例子 #include stdlib.hint main() {int* p (int*)malloc(INT_MAX);if (p NULL) {//空间开辟失败perror(malloc);return 1;}//可以使用这40个字节int i 0;for (i 0; i 10; i) {*(p i) i 1;}//释放free(p);//p指向的空间不属于当前程序但还是能找到那个空间就成了野指针了//上面就是通过代码的方式释放内存p NULL;return 0; }再看个例子 #include stdlib.hint main() {int arr[10] { 0 };int* p arr;free(p);//errp NULL;return 0; }这里因为arr不是动态开辟的所以不能用free释放。 再看个例子 int main() {//前面一堆代码int* p NULL;//中间一堆代码free(p);//什么都不干因为空指针没有指向有效的空间p NULL;return 0; }这里free什么都不干因为空指针p没有指向有效的空间。 对于malloc和free最好成对使用。 3.calloc和realloc 3.1 calloc C语言还提供了一个函数叫 calloc calloc 函数也用来动态内存分配。原型如下 void* calloc (size_t num, size_t size);函数的功能是为 num 个大小为 size 的元素开辟一块空间并且把空间的每个字节初始化为0。 与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。 举个例子 int main() {//申请10个整型的空间//malloc(10 * sizeof(int));int* p (int*)calloc(10, sizeof(int));if (p NULL) {perror(calloc);return 1;}//使用空间int i 0;for (i 0; i 10; i) {printf(%d , p[i]);}//释放free(p);p NULL;return 0; }打印 0 0 0 0 0 0 0 0 0 0所以如果我们对申请的内存空间的内容要求初始化那么可以很方便的使用calloc函数来完成任务。 3.2 realloc realloc函数的出现让动态内存管理更加灵活。 有时会我们发现过去申请的空间太小了有时候我们又会觉得申请的空间过大了那为了合理的使用内存我们一定会对内存的大小做灵活的调整。那 realloc 函数就可以做到对动态开辟内存大小的调整。 函数原型如下 void* realloc (void* ptr, size_t size);ptr 是要调整的内存地址 size 调整之后新大小 返回值为调整之后的内存起始位置。 这个函数调整原内存空间大小的基础上还会将原来内存中的数据移动到新的空间。 realloc在调整内存空间的是存在两种情况 情况1原有空间之后有足够大的空间 当是情况1 的时候要扩展内存就直接原有内存之后直接追加空间原来空间的数据不发生变化。 情况2原有空间之后没有足够大的空间 当是情况2 的时候原有空间之后没有足够多的空间时扩展的方法是 在堆空间上另找一个合适大小的连续空间来使用。这样函数返回的是一个新的内存地址。将旧的数据拷贝到新的空间释放旧的空间返回新的地址 int main() {//申请10个整型的空间//malloc(10 * sizeof(int));int* p (int*)calloc(10, sizeof(int));if (p NULL) {perror(calloc);return 1;}//使用空间int i 0;for (i 0; i 10; i) {printf(%d , p[i]);}//调整空间 - 希望变成20个整型空间//最好不要这么写p (int*)realloc(p, 20 * sizeof(int));//因为realloc可能开辟失败int* ptr (int*)realloc(p, 20 * sizeof(int));if (ptr ! NULL) {p ptr;}//使用//释放free(p);p NULL;return 0; }relloc函数不仅可以调整空间还可以申请空间。 relloc(NULL, 40);//等价于malloc(40)4.常见的动态内存的错误 4.1 对NULL指针的解引⽤操作 void test() {int *p (int *)malloc(INT_MAX/4);*p 20;//如果p的值是NULL就会有问题free(p); }例如 int main() {int* p malloc(10 * sizeof(int));if (p NULL) {perror(malloc);return 1;}//使用空间int i 0;for (i 0; i 10; i) {p[i] i;//*(pi)}free(p);p NULL;return 0; }在使用空间的时候如果p经过malloc后返回的是空指针那么就会出现对NULL指针的解引⽤操作。 我们可以在前面添加一段代码来防止这个情况发生。 int main() {int* p malloc(10 * sizeof(int));if (p NULL) {perror(malloc);return 1;}//使用空间int i 0;for (i 0; i 10; i) {p[i] i;}free(p);p NULL;return 0; }4.2 对动态开辟空间的越界访问 void test() {int i 0;int *p (int *)malloc(10*sizeof(int));if(NULL p){exit(EXIT_FAILURE);}for(i0; i10; i){*(pi) i;//当i是10的时候越界访问}free(p); }或者 void test() {int i 0;int *p (int *)malloc(10*sizeof(int));if(NULL p){exit(EXIT_FAILURE);}for(i0; i40; i)//越界访问了因为上面只分配了10个字节空间{p[i] i;}free(p); }4.3 对⾮动态开辟内存使⽤free释放 void test() {int a 10;int *p a;free(p);//err }4.4 使⽤free释放⼀块动态开辟内存的⼀部分 void test() {int *p (int *)malloc(100);p;free(p);//p不再指向动态内存的起始位置 }4.5 对同⼀块动态内存多次释放 void test() {int *p (int *)malloc(100);free(p);free(p);//重复释放 }4.6 动态开辟内存忘记释放内存泄漏 void test() {int *p (int *)malloc(100);if(NULL ! p){*p 20;}if (flag) {return;//直接返回主函数了}free(p);//并没有执行p NULL; }int main() {test();while(1); }忘记释放不再使用的动态开辟的空间会造成内存泄漏。 而且当时的动态内存的空间是通过局部变量p指针来查找的返回主函数后我们无法再次找到这个空间。我们这个时候想释放都不能释放了。只有等到主函数结束我们才能释放这个空间。这个空间实际上我们不需要用到但是程序只要不停止我们都无法释放这个空间。这个就叫内存泄漏。 有些游戏的服务器的程序可能一天24小时一直在运行这个时候动态申请的空间可能就申请申请申请可能就把内存耗光了。内存耗干了之后程序就挂了机器就重启了。 动态内存管理是一把双刃剑 它能给我们提供灵活的内存管理方式但也会带来风险 切记动态开辟的空间一定要释放并且正确释放。 5.动态内存经典笔试题分析 5.1 题⽬1 void GetMemory(char *p) {p (char *)malloc(100); } void Test(void) {char *str NULL;GetMemory(str);strcpy(str, hello world);printf(str); }int main() {Test();return 0; }请问运行Test 函数会有什么样的结果 一开始str是存放的NULL通过GetMemory()函数我们把NULL传递给了p。 p (char *)malloc(100);动态分配了100个字节的空间。 我们假设这段空间的起始地址是0x0012ff40p里面存放的自然就是0x0012ff40这个地址了因为这样才能访问到这个动态分配的空间。 可是此时str并没有改变还是NULL没有指向有效的空间。 strcpy(str, hello world); strcpy想把hello world拷贝到str指向的空间去。但是str是空指针空指针没有指向任何有效的空间形成了对空指针的非法访问而一旦对NULL指针解引用程序就会崩溃。 而且上面的GetMemory()函数结束的时候没有释放动态内存空间这就会导致内存泄漏的问题。 我们可以修改一下代码使其合理 改法1 void GetMemory(char** p) {*p (char*)malloc(100); }void Test(void) {char* str NULL;GetMemory(str);strcpy(str, hello world);printf(str);free(str);str NULL; }int main() {Test();return 0; }打印 hello world改法2 char* GetMemory() {char* p (char*)malloc(100);return p; }void Test(void) {char* str NULL;str GetMemory();strcpy(str, hello world);printf(str);free(str);str NULL; }int main() {Test();return 0; }打印 hello world5.2 题⽬2 char *GetMemory(void) {char p[] hello world;return p; } void Test(void) {char *str NULL;str GetMemory();printf(str); }int main() {Test();return 0; }请问运行Test 函数会有什么样的结果 打印随机值。 一开始是这样的。 然后GetMemory()函数返回p的地址后问题就出现了。 因为GetMemory()函数的空间早就释放了此时str指向的原来的p的地址可能早就被内存里的某些东西更改过了此时的str相当于一个野指针。 5.3 题⽬3 void GetMemory(char **p, int num) {*p (char *)malloc(num); } void Test(void) {char *str NULL;GetMemory(str, 100);strcpy(str, hello);printf(str); }int main() {Test();return 0; }请问运行Test 函数会有什么样的结果 会导致内存泄漏。 5.4 题⽬4 void Test(void) {char *str (char *) malloc(100);strcpy(str, hello);free(str);//把str指向的空间还给操作系统无法继续使用了if(str ! NULL)//这个可以判断因为地址还是那个地址只是无法使用{strcpy(str, world);//这块空间不属于他了拷贝不了形成了非法访问printf(str);} }int main() {Test();return 0; }请问运行Test 函数会有什么样的结果 free(str);把str指向的空间还给操作系统无法继续使用了str就变成野指针了。 可以在free(str);后面加上一句str NULL; 6.柔性数组 C99 中结构中的最后一个元素允许是未知大小的数组这就叫做『柔性数组』成员。 也就是满足 结构体中最后一个元素未知大小的数组 例如 struct st_type {int i;char c;int a[0];//柔性数组成员//这个0也表示数组大小未知。毕竟没有哪个数组的元素个数是0吧。 };有些编译器会报错无法编译可以改成 struct st_type {int i;char c;int a[];//柔性数组成员 };6.1 柔性数组的特点 结构中的柔性数组成员前面必须至少一个其他成员。 sizeof 返回的这种结构大小不包括柔性数组的内存。 包含柔性数组成员的结构用malloc ()函数进行内存的动态分配并且分配的内存应该大于结构的大小以适应柔性数组的预期大小。 例如 typedef struct st_type {int i;int a[0];//柔性数组成员 }type_a;int main() {printf(%d\n, sizeof(type_a));//输出的是4return 0; }打印 4一个int类型的i就占4个字节了所以a[0]没有计算在里面 6.2 柔性数组的使⽤ 代码1 #include stdio.h #include stdlib.htypedef struct st_type {int i;int a[0]; }type_a;int main() {int i 0;type_a* p (type_a*)malloc(sizeof(type_a) 100 * sizeof(int));//业务处理p-i 100;for (i 0; i 100; i){p-a[i] i;}free(p);return 0; }这样柔性数组成员a相当于获得了100个整型元素的连续空间。 6.3 柔性数组的优势 上述的 type_a 结构也可以设计为下面的结构也能完成同样的效果。 代码2 #include stdio.h #include stdlib.htypedef struct st_type {int i;int *p_a; }type_a;int main() {type_a *p (type_a *)malloc(sizeof(type_a));p-i 100;p-p_a (int *)malloc(p-i*sizeof(int));//业务处理for(i0; i100; i){p-p_a[i] i;}//释放空间free(p-p_a);p-p_a NULL;free(p);p NULL;return 0; }上述 代码1 和 代码2 可以完成同样的功能但是 代码1 的实现有两个好处 第一个好处是方便内存释放 如果我们的代码是在一个给别人用的函数中你在里面做了二次内存分配并把整个结构体返回给用户。用户调用free可以释放结构体但是用户并不知道这个结构体内的成员也需要free所以你不能指望用户来发现这个事。所以如果我们把结构体的内存以及其成员要的内存一次性分配好了并返回给用户一个结构体指针用户做一次free就可以把所有的内存也给释放掉。 第二个好处是这样有利于访问速度. 连续的内存有益于提高访问速度也有益于减少内存碎片。其实也没多高反正你跑不了要用做偏移量的加法来寻址 因为malloc()开辟的空间是连续的但是malloc()和malloc()之间的那块空间是有间隙的。 这些间隙可能会用不到叫做内存碎片。 我们也可以用realloc()函数来动态调整柔性数组。 对应上面的代码1: #include stdlib.hstruct S {int n;int arr[0];//柔性数组成员 }type_a;int main() {struct S* ps (struct S*)malloc(sizeof(struct S) 20 * sizeof(int));//这里malloc()开辟了4字节的int n;和80字节的int arr[0];if (ps NULL) {perror(malloc());return 1;}//使用这些空间ps-n 100;int i 0;for (i 0; i 20; i) {ps-arr[i] i 1;}//调整ps指向空间的大小struct S* ptr (struct S*)realloc(ps, sizeof(struct S) 40 * sizeof(int));//这里用ptr这个新的指针是为了防止realloc()开辟失败如果用ps来接收的话// 开辟失败可能就变成空指针了里面原来存的东西都没了所以要新弄个指针来接收//同时realloc()调整了原来malloc()的大小if (ptr ! NULL) {ps ptr;ptr NULL;}else {return 1;}//使用刚刚的空间for (i 0; i 40; i) {printf(%d , ps-arr[i]);}//释放空间free(ps);ps NULL;return 0; }对应上面的代码2 struct S {int n;int* arr; };int main() {struct S* ps (struct S*)malloc(sizeof(struct S));if (ps NULL) {perror(malloc());return 1;}int* tmp (int*)malloc(20 * sizeof(int));if (tmp! NULL) {ps-arr tmp;}else {return 1;}ps-n 100;int i 0;//给arr中的20个元素赋值为1~20for (i 0; i 20; i) {ps-arr[i] i 1;}//调整空间tmp (int*)realloc(ps-arr, 40 * sizeof(int));if (tmp! NULL) {ps-arr tmp;}else {perror(realloc());return 1;}for (i 0; i 40; i) {printf(%d , ps-arr[i]);}//释放空间free(ps-arr);free(ps);ps NULL;return 0; }7.总结C/C中程序内存区域划分 C/C程序内存分配的几个区域 栈区stack在执行函数时函数内局部变量的存储单元都可以在栈上创建函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中效率很高但是分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。《函数栈帧的创建和销毁》堆区heap一般由程序员分配释放 若程序员不释放程序结束时可能由OS回收 。分配方式类似于链表。数据段静态区static存放全局变量、静态数据。程序结束后由系统释放。代码段存放函数体类成员函数和全局函数的二进制代码。
http://www.zqtcl.cn/news/87486/

相关文章:

  • 网络销售是什么淘宝客网站怎样做seo
  • 网站空间的选择微信咋做自己的网站
  • 曲阜市古建设计院网站响应式网站开发步骤
  • 济南网站建设网站天津建设工程信息网密码
  • 网站首页开发收费wordpress 段落
  • 网站建设最新技术及发展趋势桓台网站制作
  • 珠海市研发网站建设重庆做seo网站优化选择哪家
  • 四川省建设厅的注册中心网站线上推广方式有哪些渠道
  • 建设官方网站意义网站开发转移合同
  • 山西集团网站建设河北手机网站建设
  • 泰安营销型网站建设网站建设话术分析
  • 手机上怎么做投票网站免费网站申请注册
  • 文案撰写网站国家时事新闻2021最新
  • 建设部网站官网 取消八大员惠城网站设计
  • 东莞企创做网站怎么样事业单位 网络网站建设
  • 贵阳网站建设kuhugz帮我做网站推广
  • 网站建设的实践目的大型社区网站开发文档
  • 在网站挂广告一个月多少钱高校信息公开网站建设
  • ps如何做网站网站开发女生
  • 哪种技术做网站容易论文答辩网站建设素材使用应该注意什么
  • 深圳 网站建设培训学校wordpress获取相关文章
  • 技术支持 中山网站建设电商网站建设属于研发费用吗
  • 江西网站建设与推广wordpress 添加图标
  • 360网站兼容模式网站不收录的技术原因
  • 内部网站建设、萤火虫网站建设优化
  • 论坛网站 备案养殖公司起名字大全免费
  • 网站app生成器windows更新wordpress
  • 不是网站建设必须经历的过程秦皇岛网站开发公司
  • 张家界搜索引擎优化seo页面代码优化
  • 网站推广计划包括哪些网络app制作网站有哪些内容