C/C++中内存分为5个区,分别为栈区、堆区、全局/静态存储区、常量存储区、代码区
静态内存分配:编译时分配,包括全局、静态全局、静态局部三种变量。
动态内存分配:运行时分配,包括栈(局部变量),堆(c语言中用到的变量被动态的分配在内存中)。
栈由编译器管理,堆的分配和释放由程序员管理。
栈是向低地址生长的数据结构,是一块连续的内存,能从栈中获得的内存较小,编译期间确定大小;堆是向高地址生长的数据结构,是一个不连续的储存空间,内存获取比较灵活,也较大。
栈:在函数调用时,第一个进栈的是主函数中的最后一条指令的地址,然后是函数的各个参数,在大多 数的c编译器中,参数是由右往左入栈的,然后是函数中的局部变量(静态变量是不入栈的),当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点开始运行;
堆:一般是在堆的头部用一个字节存放堆的大小,堆中的具体内容由程序员安排。
stdlib.h
或malloc.h
void* malloc(int size)
分配长度为 size 字节的内存块
只有一个参数,并且是整型
分配成功返回指向被分配内存的指针,否则返回空指针 NULL
返回值类型 void* ,在 C 语言中,void* 可以不经转换直接赋值给任何类型的指针变量(函数指针变量除外)
stdlib.h
或malloc.h
void* calloc(int n,int size)
分配 n 个长度为 size 字节的连续空间
分配成功返回指向分配起始地址的指针,否则返回空指针 NULL
stdlib.h
或malloc.h
void* realloc(void* mem_address,int newsize)
1.为已有内存的变量重新分配新的内存空间(可大、可小) ;
2.先判断当前的指针是否有足够的连续空间,如果有,扩大 mem_address 指向的地址,并且将 mem_ address 返回;
3.如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来 mem_address 所指内存区域(注意:原来指针是自动释放,不需要使用 free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。
分配成功返回 mem_address 所指的内存区域,否则返回空指针 NULL
动态分配的内存空间由程序员手动编程释放。
C 语言中,free 和 malloc、calloc、realloc 是成对出现的,有多少个 malloc,就应该有多少个 free 。
若 malloc、calloc、realloc 的个数比 free 多,会造成内存泄漏;若 malloc、calloc、realloc 的个数比 free 少,会造成二次删除,破坏内存,导致程序崩溃。
stdlib.h
void free(void* ptr)
释放之前调用 calloc、malloc 或 realloc 所分配的内存空间
指针指向一个要释放内存的内存块,该内存块之前是通过调用 malloc、calloc 或 realloc 进行分配内存的。如果传递的参数是一个空指针,则不会执行任何动作。
不返回任何值