1. 内存分配类型:
在C/C++中,内存分为5个区域,分别是栈区、堆区、全局/静态存储区、常量存储区、代码区。
静态内存分配:在编译时分配。 包括:全局变量、静态全局变量、静态局部变量。
动态内存分配:运行时分配。 包括: 堆栈:局部变量。 堆:C语言中使用的变量在内存中动态分配。 (或者,,自由函数)
2、变量的内存分配:
栈区(stack):指变量在需要时由编译器分配、不需要时自动清除的存储区域。 例如,当执行一个函数时,函数的形参和函数内的局部变量都被分配在堆栈区域中。 运行后,形参和局部变量从堆栈中移除(自动释放)。 堆栈内存分配操作内置于处理器的指令集中,效率很高,但分配的内存空间有限。
堆区(heap):指由程序员手动分配和释放的存储区域。 如果程序员不释放这块内存,那么这块内存就会一直被占用,直到程序被系统自动回收为止。 用在C语言中,免申请和释放空间。
静态存储区():全局变量和静态变量存储在一起,初始化后的全局变量和静态变量在一个区域。 该空间在程序结束后由系统释放。
常量存储区(const):这里存储常量字符串。 例如,“ABC”字符串存储在常量区中。 常量区中存储的字符串是只读的,不能写入。 const修饰的全局变量也存放在常量区,const修饰的局部变量仍然在栈中。
程序代码区:存放源程序的二进制代码。
2.堆和栈的比较
应用方法:栈由编译器管理,堆的分配和释放由程序员管理。
应用大小:栈是一种向低地址增长的数据结构,是一块连续的内存。 从堆栈中可以获得的内存较小,大小在编译时确定; 堆是一种向高地址增长的数据结构,是一种不连续的存储。 空间、内存获取更灵活、更大。
栈和堆中存储的内容:
栈:当函数被调用时,首先压入栈的是主函数中最后一条指令的地址,其次是函数的各个参数。 在大多数 C 编译器中,参数从右到左压入堆栈。 然后是函数中的局部变量(静态变量不会压入堆栈)。 当这个函数调用结束时,局部变量先出栈,然后是参数,最后栈顶指针指向原来存放的地址,也就是main函数。 中的下一条指令,程序从此时开始运行;
堆:一般在堆的头部用一个字节来存储堆的大小。 堆中的具体内容由程序员安排。
3.动态内存分配
1、功能;
函数原型:void *( size);
功能:
1.开辟一块大小为size的连续堆内存。
2.size表示堆上分配的内存大小(字节数)。
3、函数返回值是一个指针,指向刚刚打开的内存首地址。
4、如果内存分配失败,则返回空指针,即返回值为NULL。
5、当内存不再使用时,应使用free()函数释放内存块。
6、使用时必须包含头文件或者
2、功能;
函数原型:void *(,size t size);
功能:
1、在内存的动态存储区域分配n个连续的长度为size的空间,
2、函数返回一个指向分配起始地址的指针;
3. 如果分配不成功,则返回NULL。
4、当内存不再使用时,应使用free()函数释放内存块。
5、使用时必须包含头文件或者
3、功能;
函数原型:
void * (void * mem_ , size_ t );
功能:
1. 为现有内存变量重新分配新的内存大小(可以大也可以小);
2、首先判断当前指针是否有足够的连续空间。 如果是,则展开指向的地址并返回mem_;
3、如果空间不够,先按照指定大小分配空间,将原来的数据从头到尾复制到新分配的内存区域,然后释放原来指向的内存区域(注意:原来的指针会自动释放) ,无需使用 free) ,并返回新分配的内存区域的首地址。 即内存块的地址被重新分配。
4. 如果重新分配成功,则返回指向已分配内存的指针;
5. 如果分配不成功,则返回NULL。
6、当内存不再使用时,应使用free()函数释放内存块。
7、使用时必须包含头文件或者
4.免费功能。
函数原型:void free(void *ptr); //ptr是要释放的内存指针。
free():释放指针变量在堆区的内存空间。 它无法释放堆栈上的内存空间。 free 应与 (,) 成对使用。
注意:
如果(,)多于free,就会造成内存泄漏;
如果(,)小于free,就会造成二次删除,损坏内存,导致程序崩溃。