在程序中,数据存储在不同的区段,整个数据可以区分为:栈存储区、堆存储区、全局及静态存储区和常量存储区四个部分。
栈存储区主要存储函数参数和局部变量,这部分数据的空间由编译器负责分配和回收,其在存储数据时采用后进先出的方式。
堆存储区主要存储动态分配的内存块,这部分数据的空间由程序员负责手动分配和回收。如果程序始终没有主动释放动态分配的空间,在程序运行结束时,操作系统会回收这部分内存。
全局及静态存储区主要存储全局变量和静态变量,其生命周期在程序运行期间始终存在,在程序结束时操作系统才会回收这部分空间。
常量存储区也叫字符串常量区,用于存放字符串常量,在对字符串赋值时,会在字符串常量区开辟一块空间来存储对应的字符串常量,然后返回这块空间的地址。
栈空间和堆空间的区别:
栈空间用于存储函数参数和局部变量,所需空间由系统自动分配,回收也由系统管理,无须人工干预;堆空间用于存储动态分配的内存块,分配和释放空间均由程序员控制,有可能产生内存泄漏。
栈空间作为一个严格后进先出的数据结构,可用空间永远都是一块连续的区域;堆空间在不断分配和释放空间的过程中,可用空间链表频繁更新,造成可用空间逐渐碎片化,每块可用空间都很小。
栈空间的默认大小只有几M的空间,生长方式是向下的,也就是向着内存地址减小的方向消耗空间;堆空间的理论大小有几G的空间,生长方式是向上的,也就是向着内存地址增大的方向消耗空间。
栈空间有计算机底层的支持,压栈和出栈都有专门的指令,效率较高;堆空间通过函数动态获取空间,涉及可用空间链表的扫描和调整以及相邻可用空间的合并等操作,效率相对较低。
内存泄漏
内存泄漏是一种资源泄漏,是指计算机程序没有合理地管理已经分配的内存,导致不再使用的内存没有及时释放。随着程序运行时间的增长,泄漏的内存越积越多,可用的内存越来越少,最终无法为程序分配新的内存,进而导致程序崩溃。
原因:产生内存泄漏的原因很简单,就是分配的内存没有及时回收。具体来讲就是由于在程序中通过malloc或者new从堆中申请了一块空间,但是在使用后并没有调用free或者delete释放。
预防:用智能指针代替普通指针;借助内存泄漏检测工具;养成良好的编程习惯,保证malloc和free,new和delete成对出现。
内存越界
内存越界又称为内存访问越界,是指访问了所申请空间之外的内存。如果对越界的内存进行读操作,读取的结果具有随机性且无法预知;如果对越界的内存进行写操作,写入的结果可能会破坏其他数据。
内存越界无法从根本上避免,只能预防。