一、在C/C++中内存分为5个区,分别为栈区、堆区、全局/静态存储区、常量存储区、代码区。
静态内存分配:编译时分配。包括:全局、静态全局、静态局部三种变量。
动态内存分配:运行时分配。包括:栈(stack): 局部变量。堆(heap): c语言中用到的变量被动态的分配在内存中。(malloc或calloc、realloc、free函数)
二、变量的内存分配:
栈区(stack):指那些由编译器在需要的时候分配,不需要时自动清除的变量所在的储存区,如函数执行时,函数的形参以及函数内的局部变量分配在栈区,函数运行结束后,形参和局部变量去栈(自动释放)。栈内存分配运算内置与处理器的指令集中,效率高但是分配的内存空间有限。
堆区(heap):指哪些由程序员手动分配释放的储存区,如果程序员不释放这块内存,内存将一直被占用,直到程序运行结束由系统自动收回,c语言中使用malloc,free申请和释放空间。
静态储存区(static):全局变量和静态变量的储存是放在一块的,其中初始化的全局变量和静态变量在一个区域,这块空间当程序运行结束后由系统释放。
常量储存区(const):常量字符串就是储存在这里的,如“ABC”字符串就储存在常量区,储存在常量区的只读不可写。const修饰的全局变量也储存在常量区,const修饰的局部变量依然在栈上。
三、动态内存函数(malloc、calloc、realloc)
头文件(<stdlib.h>或<malloc.h>)
1.malloc:
函数原型:void* malloc (size_t size);
(1)开辟一块在堆区size大小的连续内存,。
(2)开辟可能失败,失败的话返回空指针,成功会函数返回一个指向分配起始地址的指针。所以需要先判断返回的指针是否为空,然后再使用。
(3)当内存不再 使用时,应使用free ()函数将内存块释放,否则会造成内存泄漏,小的程序可能影响不大,但对于中大型来说可能是致命的。
2.calloc:
函数原型:void* calloc (size_t num, size_t size);
(1)开辟一块在堆区num个长度为size大小的连续内存。
(2)开辟可能失败,失败的话返回空指针,成功会函数返回一个指向分配起始地址的指针。所以需要先判断返回的指针是否为空,然后再使用。
(3)当内存不再 使用时,应使用free ()函数将内存块释放,否则会造成内存泄漏。
(4)这个函数相比较malloc函数,它会将所分配空间的起始值赋值为0。
3.realloc
函数原型:void* realloc (void* ptr, size_t size);
(1)为已有在堆区的内存变量重新分配新的内存大小(可大、可小) .
(2)先判断当前的指针是否有足够的连续空间,如果有,扩大ptr指向的地址,并且将返回。没有就会另行开辟一块size大小的连续空间,将ptr指向的原有数据拷贝到新空间内,而后释放ptr所指内存区域(注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。
(3)重新分配内存可能失败,失败的话返回空指针,成功会函数返回一个指向分配起始地址的指针。所以需要先判断返回的指针是否为空,然后再使用。
(4)重新划分的内存可以被释放,当内存不再 使用时,应使用free ()函数将内存块释放,否则会造成内存泄漏。
4.free
函数原型:void free (void* ptr);
(1)释放在堆区上的内存free要与malloc、calloc、realloc成对使用。
(2)不要重复释放同一块空间碰坏内存,可能会导致程序崩溃。
(3)不可以释放在栈区的内存。