视频网站开发方法,简单的html网页制作模板免费,网页源代码修改了影响别人吗,淄博网站建设常见问题✨个人主页#xff1a; 熬夜学编程的小林
#x1f497;系列专栏#xff1a; 【C语言详解】 【数据结构详解】
动态内存管理
1、动态内存经典笔试题分析
1.1、题目1
1.2、题目2
1.3、题目3
1.4、题目4
2、柔性数组
2.1、柔性数组的特点
2.2、柔性数组的使用
2.3、…
✨个人主页 熬夜学编程的小林
系列专栏 【C语言详解】 【数据结构详解】
动态内存管理
1、动态内存经典笔试题分析
1.1、题目1
1.2、题目2
1.3、题目3
1.4、题目4
2、柔性数组
2.1、柔性数组的特点
2.2、柔性数组的使用
2.3、柔性数组的优势
3、总结C/C中程序内存区域划分
总结 1、动态内存经典笔试题分析 1.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 函数会有什么样的结果 根据C语言顺序结构原则进入Test()函数之后逐条执行先创建一个指针变量str指向NULL再执行GetMemory函数将 str 传入函数然后动态开辟100字节空间但是指针变量 p 出了函数会自动销毁然后执行strcpy函数但是此处str 指向NULL 程序对NULL进行解引用操作程序崩溃 前面函数动态开辟内存没有手动释放因此 会导致内存泄漏 。 1.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 函数会有什么样的结果 根据C语言顺序结构原则进入Test()函数之后逐条执行先创建一个指针变量str指向NULL再执行GetMemory函数将数组首元素地址作为返回值返回给str但是此处是在栈区开辟的空间函数结束后就会销毁此时str就为野指针 打印野指针(非法访问内存)就会出现肉眼看不懂的文字。 1.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 函数会有什么样的结果 根据C语言顺序结构原则进入Test()函数之后逐条执行先创建一个指针变量str指向NULL再执行GetMemory函数将str的地址传入函数将*p开辟100个内存空间即给str开辟100个内存空间然后执行strcpy函数将hello\0拷贝到str再将str打印出来此处没有太大问题唯一的问题是 str指向的空间是动态开辟的没有手动释放会导致内存泄漏。 1.4、题目4 void Test(void){char *str (char *) malloc(100);strcpy(str, hello);free(str);if(str ! NULL){strcpy(str, world);printf(str);}}
int main()
{Test();return 0;
} 请问运行Test 函数会有什么样的结果 根据C语言顺序结构原则进入Test()函数之后逐条执行先创建一个指针变量str指向动态开辟100字节的空间然后将该空间拷贝hello\0然后释放该空间(只是不能正常使用实际还是指向该位置)此时str还是指向动态开辟的空间因此指向strcpy函数将world\0拷贝到str然后打印str即 打印出world只是str为野指针即非法访问内存。 2、柔性数组 也许你从来没有听说过柔性数组flexible array这个概念但是它确实是存在的。 C99 中 结构中 的 最后⼀个元素 允许是 未知大小的数组 这就叫做『柔性数组』成员。 例如 typedef struct st_type
{int i;int a[0];//柔性数组成员
}type_a; 有些编译器会报错无法编译可以改成 typedef struct st_type
{int i;int a[];//柔性数组成员
}type_a; 2.1、柔性数组的特点 • 结构中的柔性数组成员前面必须至少⼀个其他成员。 • sizeof 返回的这种结构大小不包括柔性数组的内存。 • 包含柔性数组成员的结构用malloc ()函数进行内存的动态分配并且分配的内存应该大于结构的大小以适应柔性数组的预期大小。 例如 typedef struct st_type
{int i;int a[0];//柔性数组成员
}type_a;
int main()
{printf(%d\n, sizeof(type_a));//输出的是4return 0;
} 2.2、柔性数组的使用 //代码1
#include stdio.h
#include stdlib.h
typedef 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(i0; i100; i){p-a[i] i;}free(p);return 0;
} 这样柔性数组成员a相当于获得了100个整型元素的连续空间。 2.3、柔性数组的优势 上述的 type_a 结构也可以设计为下面的结构也能完成同样的效果 //代码2
#include stdio.h
#include stdlib.h
typedef 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就可以把所有的内存也给释放掉。 第⼆个好处是这样有利于访问速度. 连续的内存有益于提高访问速度也有益于减少内存碎片。其实我个⼈觉得也没多高了反正你跑不了要用做偏移量的加法来寻址 扩展阅读 C语⾔结构体里的数组和指针https://coolshell.cn/articles/11377.html 3、总结C/C中程序内存区域划分 C/C程序内存分配的几个区域 1. 栈区stack在执行函数时函数内局部变量的存储单元都可以在栈上创建函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中效率很高但是分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。 2. 堆区heap⼀般由程序员分配释放 若程序员不释放程序结束时可能由OS回收 。分配方式类似于链表。 3. 数据段静态区static存放全局变量、静态数据。程序结束后由系统释放。 4. 代码段存放函数体类成员函数和全局函数的⼆进制代码。 总结 本篇博客就结束啦谢谢大家的观看如果公主少年们有好的建议可以留言喔谢谢大家啦