C语言 动态内存分配
2017-02-27 17:13
204 查看
前言 :我们知道内存分为 栈 堆 其实在计算机中是不存在差别的,只是程序员手动分类 方便处理
案例1 我们直接创建一个在栈区的40m大小数组
案例2 在堆区创建一个40m的数组
案例3 多次动态分配堆内存 不释放
案例4 手动释放内存
案例5 申请内存另一个api
案例6 DEMO
realloc
C语言内存分配:
1. 栈区(stack)
windows下,栈内存分配2M(确定的常数),超出了限制,提示stack overflow错误
自动分配,释放
2. 堆区(heap)
程序员手动分配释放,操作系统80%内存
3. 全局区或静态区
4. 字符常量区
5. 程序代码区
结果:栈溢出
malloc函数分配堆内存并返回对应指针 头文件stdlib.h
sizeof 返回对应变量所占字节数
结果:正常
在执行睡眠的时候我们看看程序所占内存大小40mb
睡眠结束后 程序内存变为80mb
我们申请了两次内存分别为40mb,发现再第二次申请的时候内存所占变为80 可见第一次申请的内存并没有释放
上面的代码运行预期结果应该是:手动释放了第一次申请的40mb 内存 ,然后有申请了一次40mb 所以程序运行结束休眠后应该还是40mb
结果:和预期一致
注意新申请的内存 可能会在原来内存地址上基础上扩展/缩小,也有可能在某个新的内存地址段 申请一块 并且拷贝旧数据到新内存,同时释放旧内存
百度百科 :
realloc分配一个newsize的内存块,返回一个指向该内存块的指针。
如果newsize大小为0,那么释放mem_address指向的内存,并返回NULL。
如果没有足够可用的内存用来完成重新分配(扩大原来的内存块或者分配新的内存块),则返回NULL。而原来的内存块保持不变。
现存的数据然后就被拷贝至新的位置,而老块则放回到堆上.重要的信息就是数据可能被移动
总结:
realloc失败的时候,返回NULL
realloc失败的时候,原来的内存不改变,不会释放也不会移动
假如原来的内存后面还有足够多剩余内存的话,realloc的内存=原来的内存+剩余内存,realloc还是返回原来内存的地址; 假如原来的内存后面没有足够多剩余内存的话,realloc将申请新的内存,然后把原来的内存数据拷贝到新内存里,原来的内存将被free掉,realloc返回新内存的地址
如果size为0,效果等同于free()。这里需要注意的是只对指针本身进行释放,例如对二维指针**a,对a调用realloc时只会释放一维,使用时谨防内存泄露。
传递给realloc的指针必须是先前通过malloc(), calloc(), 或realloc()分配的
6.传递给realloc的指针可以为空,等同于malloc。
案例1 我们直接创建一个在栈区的40m大小数组
案例2 在堆区创建一个40m的数组
案例3 多次动态分配堆内存 不释放
案例4 手动释放内存
案例5 申请内存另一个api
案例6 DEMO
realloc
C语言内存分配:
1. 栈区(stack)
windows下,栈内存分配2M(确定的常数),超出了限制,提示stack overflow错误
自动分配,释放
2. 堆区(heap)
程序员手动分配释放,操作系统80%内存
3. 全局区或静态区
4. 字符常量区
5. 程序代码区
案例1 我们直接创建一个在栈区的40m大小数组
void main(){ int aaasd[1024 * 1024 * 10]; }
结果:栈溢出
案例2 在堆区创建一个40m的数组
#include <stdlib.h> void main(){ int * a = malloc(sizeof(int)* 1024 * 1024 * 10); getchar(); }
malloc函数分配堆内存并返回对应指针 头文件stdlib.h
sizeof 返回对应变量所占字节数
结果:正常
案例3 多次动态分配堆内存 不释放
void main(){ int * a = malloc(sizeof(int)* 1024 * 1024 * 10); //休眠程序10秒 头文件#include <Windows.h> Sleep(10000); a = malloc(sizeof(int)* 1024 * 1024 * 10); getchar(); }
在执行睡眠的时候我们看看程序所占内存大小40mb
睡眠结束后 程序内存变为80mb
我们申请了两次内存分别为40mb,发现再第二次申请的时候内存所占变为80 可见第一次申请的内存并没有释放
案例4 手动释放内存
void main(){ int * a = malloc(sizeof(int)* 1024 * 1024 * 10); //释放 a所指向的内存 free(a); //休眠程序10秒 头文件#include <Windows.h> Sleep(10000); a = malloc(sizeof(int)* 1024 * 1024 * 10); getchar(); }
上面的代码运行预期结果应该是:手动释放了第一次申请的40mb 内存 ,然后有申请了一次40mb 所以程序运行结束休眠后应该还是40mb
结果:和预期一致
案例5 申请内存另一个api
void main(){ //第一个参数申请数量, 每个申请数量的大小 那么这里还是申请40mb int * a = calloc(1024*1024*10,sizeof(int)); getchar(); }
案例6 DEMO
void main(){ //第一个参数申请数量, 每个申请数量的大小 那么这里还是申请40mb int * a = calloc(1024*1024*10,sizeof(int)); //内存申请成功 if (a!=NULL) { //xXXXX之后释放内存 free(a); a = NULL; }else{ //内存申请失败 } getchar(); }
realloc
内存重新分配,当你动态内存申请40mb的数组此时你不够用怎么办?便可以重新调用realoc来重新分配内存void main(){ //第一个参数申请数量, 每个申请数量的大小 那么这里还是申请40mb int * a = calloc(1024 * 1024 * 10, sizeof(int)* 2); //重新申请80mb 第一次申请的内存区域如果和新申请的区域不再同一段 那么 赋值数据到新内存段,并释放久指针内存区域 int * b=realloc(a, 1024 * 1024 * 10 * sizeof(int)* 2); getchar(); }
注意新申请的内存 可能会在原来内存地址上基础上扩展/缩小,也有可能在某个新的内存地址段 申请一块 并且拷贝旧数据到新内存,同时释放旧内存
百度百科 :
realloc分配一个newsize的内存块,返回一个指向该内存块的指针。
如果newsize大小为0,那么释放mem_address指向的内存,并返回NULL。
如果没有足够可用的内存用来完成重新分配(扩大原来的内存块或者分配新的内存块),则返回NULL。而原来的内存块保持不变。
现存的数据然后就被拷贝至新的位置,而老块则放回到堆上.重要的信息就是数据可能被移动
总结:
realloc失败的时候,返回NULL
realloc失败的时候,原来的内存不改变,不会释放也不会移动
假如原来的内存后面还有足够多剩余内存的话,realloc的内存=原来的内存+剩余内存,realloc还是返回原来内存的地址; 假如原来的内存后面没有足够多剩余内存的话,realloc将申请新的内存,然后把原来的内存数据拷贝到新内存里,原来的内存将被free掉,realloc返回新内存的地址
如果size为0,效果等同于free()。这里需要注意的是只对指针本身进行释放,例如对二维指针**a,对a调用realloc时只会释放一维,使用时谨防内存泄露。
传递给realloc的指针必须是先前通过malloc(), calloc(), 或realloc()分配的
6.传递给realloc的指针可以为空,等同于malloc。
相关文章推荐
- c语言-动态内存分配
- C语言基本教程 第10课: 动态内存分配
- 【C语言天天练(九)】动态内存分配
- C语言——存储类和动态内存分配
- 黑马程序员--C语言指针与动态内存分配
- C语言学习笔记24——动态内存分配
- c语言基础(六)静态和动态内存分配
- 【C语言天天练(九)】动态内存分配
- C语言 动态内存分配
- C语言 指针及动态内存分配
- C语言回顾 十 动态内存分配
- 16.从零开始学习C语言--动态内存分配
- C语言指针学习(三) ---- 动态内存分配
- C语言-动态内存分配
- 【C语言复习(二十)】动态内存分配
- C语言10 -- 动态内存分配
- [C语言] 数据结构-预备知识动态内存分配
- iOS开发学习之C语言---C09 动态内存分配
- C语言编程入门——动态内存分配
- C语言-动态内存分配