目录
a.operator new 与 operator delete函数
一.动态内存管理的前置知识
我们在代码中用来存储数据的空间一共有这么几类:栈区、堆区、全局/静态区和常量区。那么,它们分别有什么用?相互间又有何区别?
1.栈区
栈区由编译器自动分配和释放,主要存储局部变量、函数参数等。栈区的内存分配是自动的,且按照后进先出(后定义的变量会先被释放)的原则进行。
a.栈区的特点
①后进先出:栈区的数据结构是一个栈,即只能在一端(栈顶)进行数据的压入(push)和弹出(pop)操作。新加入的数据会被放在栈顶,而最后加入的数据会最先被弹出。
②自动管理内存:栈区的内存分配和释放是由操作系统自动完成的,无需我们手动干预。当函数调用时,系统会为其分配一块栈空间用于存储局部变量和参数等;当函数返回时,系统会自动回收这块栈空间。
③存储效率高:由于栈区的数据结构相对简单,且内存分配和释放是自动完成的,因此栈区的存储效率较高,访问速度也较快。
b.注意事项
①避免栈溢出:栈溢出是指由于栈空间不足而导致的程序崩溃或异常,这一般是由于递归调用过深、局部变量过大或数组越界等问题,所以,在编写代码时,我们应该注意这类问题~~
②注意变量的作用域和生命周期:栈区中的变量具有明确的作用域和生命周期,它们只在定义它们的函数内部可见,并在函数返回时失效。
③避免野指针和内存泄漏:虽然栈区的内存是由系统自动管理的,但我们仍需注意避免野指针和内存泄漏等问题。例如,不要将栈区中的变量地址赋给全局指针或传递给其他函数,以免在变量失效后仍然使用该地址。
2.堆区
堆区是程序运行时用于动态分配内存的区域。与栈区不同,堆区的内存分配不是由编译器自动完成的,而是由程序员根据需要在程序运行时显式地申请和释放。这种动态内存分配方式提供了更大的灵活性,允许程序在运行时根据需要调整内存使用。
a.堆区的特点
堆区的内存通常是不连续的,因为系统使用链表等数据结构来管理空闲内存块。这种不连续性使得堆区的内存分配和释放相对复杂,但也提供了更大的灵活性。
b.注意事项
避免内存泄漏:内存泄漏是指程序在运行时未能正确释放已分配的内存,导致内存占用不断增加。为了避免内存泄漏,我们应确保在不再需要使用堆区上的内存时及时释放它。
避免野指针:野指针是指访问指向无效内存地址的指针。这通常发生在释放内存后未将指针置NULL,然后再次使用该指针。所以,我们应在释放内存后将指针置为NULL。
3.全局/静态区
全局/静态区是内存中用于存储全局变量和静态变量的区域。全局变量是在所有函数外部定义的变量,而静态变量则可以通过在变量前加上 static 关键字来声明,无论是在函数内部还是外部。
a.作用域和生命周期
作用域:全局变量的作用域是整个程序,即它们可以在程序的任何位置被访问和修改。而静态变量仅在定义它们的函数内部可见。
生命周期:全局变量的生命周期从程序开始执行到程序结束。它们在程序启动时被分配内存,并在程序结束时被释放。