避免网站 404,wordpress wp_head函数,wordpress justnews,不用下载就可以登录微信内存分配方式
简介
在C中#xff0c;内存分成5个区#xff0c;他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。 栈#xff1a;在执行函数时#xff0c;函数内局部变量的存储单元都可以在栈上创建#xff0c;函数执行结束时这些存储单元自动被释放。栈内存…内存分配方式
简介
在C中内存分成5个区他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。 栈在执行函数时函数内局部变量的存储单元都可以在栈上创建函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中效率很高但是分配的内存容量有限。堆就是那些由 new分配的内存块他们的释放编译器不去管由我们的应用程序去控制一般一个new就要对应一个 delete。如果程序员没有释放掉那么在程序结束后操作系统会自动回收。自由存储区就是那些由malloc等分配的内存块他和堆是十分相似的不过它是用free来结束自己的生命的。全局/静态存储区全局变量和静态变量被分配到同一块内存中在以前的C语言中全局变量又分为初始化的和未初始化的在C里面没有这个区分了他们共同占用同一块内存区。常量存储区这是一块比较特殊的存储区他们里面存放的是常量不允许修改。明确区分堆与栈
堆与栈的区分问题似乎是一个永恒的话题由此可见初学者对此往往是混淆不清的所以我决定拿他第一个开刀。 首先我们举一个例子
void f() { int* pnew int[5]; }这条短短的一句话就包含了堆与栈看到new我们首先就应该想到我们分配了一块堆内存那么指针p呢他分配的是一块栈内存所以这句话的意思就是在栈内存中存放了一个指向一块堆内存的指针p。在程序会先确定在堆中分配内存的大小然后调用operator new分配内存然后返回这块内存的首地址放入栈中。
堆和栈究竟有什么区别 好了我们回到我们的主题堆和栈究竟有什么区别 主要的区别由以下几点 (1). 管理方式不同 (2). 空间大小不同 (3). 能否产生碎片不同 (4). 生长方向不同 (5). 分配方式不同 (6). 分配效率不同
管理方式不同对于栈来讲是由编译器自动管理无需我们手工控制对于堆来说释放工作由程序员控制容易产生memory leak。空间大小一般来讲在32位系统下堆内存可以达到4G的空间从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲一般都是有一定的空间大小的例如在VC6下面默认的栈空间大小是1M好像是记不清楚了。当然我们可以修改打开工程依次操作菜单如下Project-Setting-Link在Category 中选中Output然后在Reserve中设定堆栈的最大值和commit。 注意reserve最小值为4Bytecommit是保留在虚拟内存的页文件里面它设置的较大会使栈开辟较大的值可能增加内存的开销和启动时间。 碎片问题对于堆来讲频繁的new/delete势必会造成内存空间的不连续从而造成大量的碎片使程序效率降低。对于栈来讲则不会存在这个问题因为栈是先进后出的队列他们是如此的一一对应以至于永远都不可能有一个内存块从栈中间弹出在他弹出之前在他上面的后进的栈内容已经被弹出详细的可以参考数据结构这里我们就不再一一讨论了。 生长方向对于堆来讲生长方向是向上的也就是向着内存地址增加的方向对于栈来讲它的生长方向是向下的是向着内存地址减小的方向增长。 分配方式堆都是动态分配的没有静态分配的堆。栈有2种分配方式静态分配和动态分配。静态分配是编译器完成的比如局部变量的分配。动态分配由alloca函数进行分配但是栈的动态分配和堆是不同的他的动态分配是由编译器进行释放无需我们手工实现。 分配效率栈是机器系统提供的数据结构计算机会在底层对栈提供支持分配专门的寄存器存放栈的地址压栈出栈都有专门的指令执行这就决定了栈的效率比较高。堆则是C/C函数库提供的它的机制是很复杂的例如为了分配一块内存库函数会按照一定的算法具体的算法可以参考数据结构/操作系统在堆内存中搜索可用的足够大小的空间如果没有足够大小的空间可能是由于内存碎片太多就有可能调用系统功能去增加程序数据段的内存空间这样就有机会分到足够大小的内存然后进行返回。显然堆的效率比栈要低得多。 从这里我们可以看到堆和栈相比由于大量new/delete的使用容易造成大量的内存碎片由于没有专门的系统支持效率很低由于可能引发用户态和核心态的切换内存的申请代价变得更加昂贵。所以栈在程序中是应用最广泛的就算是函数的调用也利用栈去完成函数调用过程中的参数返回地址EBP和局部变量都采用栈的方式存放。所以我们推荐大家尽量用栈而不是用堆。 虽然栈有如此众多的好处但是由于和堆相比不是那么灵活有时候分配大量的内存空间还是用堆好一些。 无论是堆还是栈都要防止越界现象的发生除非你是故意使其越界因为越界的结果要么是程序崩溃要么是摧毁程序的堆、栈结构产生以想不到的结果,就算是在你的程序运行过程中没有发生上面的问题你还是要小心说不定什么时候就崩掉那时候debug可是相当困难的
C中内存泄漏的几种情况
1. 在类的构造函数和析构函数中没有匹配的调用new和delete函数 两种情况下会出现这种内存泄露一是在堆里创建了对象占用了内存但是没有显示地释放对象占用的内存二是在类的构造函数中动态的分配了内存但是在析构函数中没有释放内存或者没有正确的释放内存 2. 在释放对象数组时在delete中没有使用方括号
8. 没有将基类的析构函数定义为虚函数 当父类指针指向子类对象时如果基类的析构函数不是virtual那么子类的析构函数将不会被调用子类的资源没有正确是释放因此造成内存泄露。