编程情况经常涉及动态数据或输入,其中数据项的数量会随着程序的运行而变化。一个实际的例子是为公司处理员工列表的应用程序。当姓名添加到列表时,列表会扩展;当姓名从列表中删除时,列表会收缩。内存会为列表分配空间以适应额外的数据项,因为姓名会变长。在这种情况下,程序员需要使用动态内存管理策略。
在程序执行之前,所有内存需求都通过声明所需的变量来确定。然而,在某些情况下,程序的内存需求可能只在运行时才知道。例如,当所需的内存量由用户输入决定时。在这些情况下,程序必须动态分配内存,这就是 C++ 语言内置支持 `new` 和 `delete` 运算符的原因。本文介绍了 C++ 中的动态内存分配。
内存分配是为程序中的变量、结构体和类实例指定内存空间的过程。程序执行时会分配内存。`new` 运算符用于分配内存,而 `delete` 运算符用于释放内存。
对于 C++ 程序,内存架构包括:
在静态内存分配中,内存由编译器独立分配和释放。在编译时,我们必须指定所需的内存量。编译器在静态内存分配期间确定这些变量需要多少内存,并为其存储固定一个位置。将要存储的变量的位置使用表格保存。但是,在编译时不会为变量分配任何物理内存。
内存是在程序运行期间动态分配的。但是,在这种情况下,当不再需要动态分配的内存时,由程序员负责释放它。否则,会发生内存泄漏。在程序运行时,程序员可以动态分配存储空间,但他们无法“即时”发明新的变量名,因此动态分配需要满足两个要求:
内存释放是这个概念的另一个方面,其中为变量或其他数据存储“清理”空间。程序员负责释放动态生成的空间。我们使用 `delete` 运算符来释放动态内存。或者,“动态内存分配”一词指的是手动管理动态内存分配的内存。
内存泄漏是由不正确的内存分配和释放实践引起的。最常见的是,它发生在动态内存分配时。因为 C++ 不像 Java 那样具有自动垃圾回收功能,所以程序员负责分配指针所需的内存。
内存泄漏的一个真实世界示例是酒店电梯的滥用。假设您租住在一栋 19 层高的公寓楼里。您想去 10 楼,于是按下了按钮召唤电梯。20 分钟以来,电梯的状态一直显示为地下室。当您调查时,您发现孩子们在地下室玩耍并堵住了电梯入口。然后您意识到有些地方不对劲。
同样,指针在完成其操作后应释放其使用的内存。这样内存就可以被其他变量适当地管理和使用。
可以使用 `delete` 关键字删除已分配的内存。
如果您(程序员)想为一个 40 个字符的字符串分配内存,那是一个字符数组。下一个示例展示了程序员如何使用相同的技术动态分配内存。
char* val = NULL; // Pointer initialized with NULL value
val = new char[40]; // Request memory for the variable
#include <iostream>
using namespace std;
class stud {
public:
stud()
{
cout << "Constructor Used" << endl;
}
~stud()
{
cout << "Destructor Used" << endl;
}
};
int main()
{
stud* S = new stud[6];
delete[] S;
}
输出
Constructor Used Constructor Used Constructor Used Destructor Used Destructor Used Destructor Used
对于 C 中的动态内存分配,我们使用 `calloc()` 和 `malloc()` 方法。使用 `free()`,我们可以释放该内存。C++ 也支持这些函数。但是,在 C++ 中不鼓励使用这些函数。
C++ 中的 `new` 和 `delete` 这两个一元运算符能够有效地进行动态内存分配和释放。
数组的大小通常在运行时才已知。在这种情况下,动态内存分配非常有用。它提高了内存管理效率。
为数组分配内存块的语法:
pointer_variable = new data_type[size];
语法:如果多维数组大小为 m x n
pointer_variable = new data_type[m][n];
以下语法将释放任何数组的内存空间:
delete [ ] pointer_variable;
#include <iostream>
using namespace std;
int main() {
int *ptr = new(nothrow) int[20];
if(!ptr){
cout<<"Sorry Failed! Memory not available."<<endl;
exit(1);
}
for(int i=0; i<20; i++){
ptr[i]=i+1;
}
for(int i=0; i<20; i++){
cout<<ptr[i]<<" ";
}
delete [] ptr;
return 0;
}
输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20