前言 :我们知道内存分为 栈 堆 其实在计算机中是不存在差别的,只是程序员手动分类 方便处理
案例1 我们直接创建一个在栈区的40m大小数组案例2 在堆区创建一个40m的数组案例3 多次动态分配堆内存 不释放案例4 手动释放内存案例5 申请内存另一个api案例6 DEMOrealloc
C语言内存分配: 1. 栈区(stack) windows下,栈内存分配2M(确定的常数),超出了限制,提示stack overflow错误 自动分配,释放 2. 堆区(heap) 程序员手动分配释放,操作系统80%内存 3. 全局区或静态区 4. 字符常量区 5. 程序代码区
结果:栈溢出
malloc函数分配堆内存并返回对应指针 头文件stdlib.h sizeof 返回对应变量所占字节数
结果:正常
在执行睡眠的时候我们看看程序所占内存大小40mb
睡眠结束后 程序内存变为80mb
我们申请了两次内存分别为40mb,发现再第二次申请的时候内存所占变为80 可见第一次申请的内存并没有释放
上面的代码运行预期结果应该是:手动释放了第一次申请的40mb 内存 ,然后有申请了一次40mb 所以程序运行结束休眠后应该还是40mb
结果:和预期一致
内存重新分配,当你动态内存申请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失败的时候,返回NULLrealloc失败的时候,原来的内存不改变,不会释放也不会移动假如原来的内存后面还有足够多剩余内存的话,realloc的内存=原来的内存+剩余内存,realloc还是返回原来内存的地址; 假如原来的内存后面没有足够多剩余内存的话,realloc将申请新的内存,然后把原来的内存数据拷贝到新内存里,原来的内存将被free掉,realloc返回新内存的地址如果size为0,效果等同于free()。这里需要注意的是只对指针本身进行释放,例如对二维指针**a,对a调用realloc时只会释放一维,使用时谨防内存泄露。传递给realloc的指针必须是先前通过malloc(), calloc(), 或realloc()分配的 6.传递给realloc的指针可以为空,等同于malloc。新闻热点
疑难解答