内存管理总结 公众号CppCoding内存管理基础作用域C语言变量的作用域分为- 代码块作用域{代码块是{}之间的一段代码}- 函数作用域- 文件作用域局部变量局部变量也叫auto自动变量一般情况下代码块{}内部定义的变量都是自动变量其特点- 在一个函数内定义只在函数范围内有效- 在复合语句中定义只在复合语句中有效- 随着函数调用的结束或复合语句的结束局部变量的声明声明周期结束- 如果没有赋初值内容为随机#includestdio.hvoidtest(){//auto写不写是一样的//auto只能出现在{}内部autointb10;}intmain(void){//b 100; //err 在main作用域中没有bif(1){//在复合语句中定义只在复合语句中有效inta10;printf(a %d\n,a);}//a 10; //err离开if()的复合语句a已经不存在return0;}静态static局部变量static局部变量的作用域也是在定义的函数内有效static局部变量的生命周期和程序运行周期一样同时static局部变量的值只初始化一次但是可以多次赋值static局部变量若未赋以初值则由系统自动赋值数值型变量自动赋初值0字符型变量赋空字符#includestdio.hvoidfun1(){inti0;i;printf(i %d\n,i);}voidfun2(){//静态局部变量没有赋值系统赋值为0而且只会初始化一次staticinta;a;printf(a %d\n,a);}intmain(void){fun1();fun1();fun2();fun2();return0;}全局变量在函数外定义可被本文件及其他文件中的函数所共用若其他文件中的函数调用此变量须用extern声明全局变量的生命周期和程序运行周期一样不同文件的全局变量不可重名静态全局变量static在函数外定义作用范围被限制在所定义的文件中不同文件静态全局变量可以重名但作用域不冲突static全局变量的生命周期和程序运行周期一样同时static全局变量的值只初始化一次extern全局变量声明extern int a;声明一个变量这个变量在别的文件中已经定义这里只是声明而不是定义https://blog.csdn.net/he__yuan/article/details/81516264全局函数和静态函数在C语言中函数默认都是全局的使用关键字static可以将函数声明为静态函数定义为static就意味着这个函数只能在定义这个函数的文件使用其他文件不可以使用即使在其他文件中声明这个函数都没有用对于不同文件中的static函数名字可以相同注意- 允许在不同的函数中使用相同的变量名他们代表不同的对象分配不同的单元互不干扰- 同一源文件中允许全局变量和局部变量同名在局部变量的作用域内全局变量不起作用- 所有的函数默认都是全局的意味着所有的函数都不能重名但是如果是static函数那么作用域是文件级的所以不同的文件static函数名都是可以相同的内存布局内存分区C代码经过预处理、编译、汇编、链接后生成一个可执行程序。代码区存放CPU执行的机器指令。通常代码区是可共享的即另外的执行程序可以调用它使其可共享的目的是对于频繁被执行的程序只需要在内存中有一份代码即可。代码区通常是只读的使其只读的原因是防止程序意外的修改了他的指令。另外代码区还规划了局部变量的相关信息。全局初始化数据区/静态数据区data段该区包含了在程序中明确被初始化的全局变量、已经初始化的静态变量包括全局静态变量和局部静态变量和常量数据如字符串常量。未初始化数据区bss存入的是全局未初始化变量和未初始化静态变量。未初始化数据区的数据在程序开始执行之前被内核初始化0或者为空NULL。程序在加载到内存前代码区和全局区data和bss的大小是固定的程序运行期间不能改变。然后运行可执行程序系统把程序加载到内存除了根据可执行程序的信息分出代码区text、数据区data和未初始化数据区bss区之外还额外增加栈区和堆区。这五部分内容代码区text segment加载的是可执行文件代码段所有的可执行代码都加载到代码区这块内存是不可以在运行期间修改的未初始化数据区bss加载的是可执行BSS段位置可以分开也可以紧靠数据段存储于数据段的数据全局未初始化静态未初始化数据的声明周期为整个程序运行过程全局初始化数据区/静态数据区data segment加载的是可执行文件数据段存储于数据段全局初始化静态初始化数据文字常量只读的数据的生命周期为整个程序运行过程栈区stack栈是一种先进后出的内存结构由编译器自动分配释放存放函数的参数值、返回值、局部变量等。在程序运行过程中实时加载和释放因此局部变量的生存周期为申请到释放该段栈空间堆区heap堆是一个大容器它的容量要远远大于栈但没有栈那样先进后出的顺序。用于动态内存分配堆在内存中位于BSS区和栈区之间。一般由程序员分配和释放若程序员不释放程序结束时由操作系统回收存储类型总结存储类型总结内存操作函数memset()#includestring.hvoid*memset(void*s,intc,size_t n);功能将s的内存区的前n个字节以参数c填入 参数 s需要操作内存s的首地址 c填充的字符c虽然参数为int但必须是unsignedchar,范围为0~255n指定需要设置的大小 返回值s的首地址memcpy()#includestring.hvoid*memcpy(void*dest,constvoid*src,size_t n);功能拷贝src所指的内存内容的前n个字节到dest所值的内存地址上。 参数 dest目的内存首地址 src源内存首地址注意dest和src所指的内存空间不可重叠 n需要拷贝的字节数 返回值dest的首地址memmove()memmove()功能用法和memcpy()一样区别在于dest和src所指的内存空间重叠时memmove()仍然能处理不过执行效率比memcpy()低一些memcmp()#includestring.hintmemcmp(constvoid*s1,constvoid*s2,size_t n);功能比较s1和s2所指向内存区域的前n个字节 参数 s1内存首地址1s2内存首地址2n需比较的前n个字节 返回值 相等0大于0小于0**堆区内存分配和释放**malloc()java #includestdlib.hvoid*malloc(size_t size);功能在内存的动态存储区(堆区)中分配一块长度为size字节的连续区域用来存放类型说明符指定的类型。分配的内存空间内容不确定一般使用memset初始化。 参数 size需要分配内存大小(单位字节)返回值 成功分配空间的起始地址 失败NULLfree()#includestdlib.hvoidfree(void*ptr);功能释放ptr所指向的一块内存空间ptr是一个任意类型的指针变量指向被释放区域的首地址。对同一内存空间多次释放会出错。 参数 ptr需要释放空间的首地址被释放区应是由malloc函数所分配的区域。 返回值无https://blog.csdn.net/qq_42322103/article/details/99089546