理解c++中动态内存分配的使用
understanding the use of dynamic memory allocation in c++
考虑这个程序:
#include <iostream>
using namespace std;
int main ()
{
int i;
cout << "How many numbers would you like to type? ";
cin >> i;
int * p;
p= new int[i];
cout << "Enter the numbers: \n";
for (int n=0; n<i; n++)
cin >> p[n];
cout << "You have entered: ";
for (int n=0; n<i; n++)
cout << p[n] << ", ";
delete[] p;
return 0;
}
还有这个:
#include <iostream>
using namespace std;
int main()
{
int num;
cout << "How many numbers would you like to type? ";
cin >> num;
int arr[num];
cout << "Enter the numbers: \n";
for (int a = 0; a <num; ++a)
cin >>arr[a];
cout << "You have entered: ";
for (int a = 0; a <num; ++a)
cout <<arr[a]<< ", ";
return 0;
}
两个程序都在完成相同的任务,而且 - 对我来说 - 后者很多
比前者更容易理解。现在我的问题是为什么我们仍然需要动态内存分配?
当 num
不是编译器时间常数时,int arr[num];
是 VLA(可变长度数组),这不是标准的 C++。它是一些编译器提供的语言扩展(我假设你使用的是 G++)。
同样易于使用且不需要您使用原始指针和处理手动动态分配的东西是 std::vector
:
int i;
cout << "How many numbers would you like to type? ";
if (!(cin >> i)) { // error checking is important
cout << "Not a number, abort!\n";
return 1;
}
std::vector<int> numbers(i);
cout << "Enter the numbers: \n";
for (int a = 0; a < i; ++a)
cin >> numbers[a];
考虑如果您创建的这个数组需要在创建它的函数的作用域之外继续存在会发生什么。例如,如果这不是 main()
函数,而是 returns 到 main 的内存。或者您可能无法提前知道要创建多少个对象。例如,您可以维护基于动态实时数据的树或基于图形的数据结构。
在您给出的简单示例中,您是正确的:在堆上动态分配数组可能是一种浪费,如果做得不好,很容易导致内存泄漏等问题(尽管有一些解决方法,例如使用现代 RAII 技术进行所有分配)。但如果有动态内存可用,更复杂的场景会变得简单得多。
考虑这个程序:
#include <iostream>
using namespace std;
int main ()
{
int i;
cout << "How many numbers would you like to type? ";
cin >> i;
int * p;
p= new int[i];
cout << "Enter the numbers: \n";
for (int n=0; n<i; n++)
cin >> p[n];
cout << "You have entered: ";
for (int n=0; n<i; n++)
cout << p[n] << ", ";
delete[] p;
return 0;
}
还有这个:
#include <iostream>
using namespace std;
int main()
{
int num;
cout << "How many numbers would you like to type? ";
cin >> num;
int arr[num];
cout << "Enter the numbers: \n";
for (int a = 0; a <num; ++a)
cin >>arr[a];
cout << "You have entered: ";
for (int a = 0; a <num; ++a)
cout <<arr[a]<< ", ";
return 0;
}
两个程序都在完成相同的任务,而且 - 对我来说 - 后者很多
比前者更容易理解。现在我的问题是为什么我们仍然需要动态内存分配?
当 num
不是编译器时间常数时,int arr[num];
是 VLA(可变长度数组),这不是标准的 C++。它是一些编译器提供的语言扩展(我假设你使用的是 G++)。
同样易于使用且不需要您使用原始指针和处理手动动态分配的东西是 std::vector
:
int i;
cout << "How many numbers would you like to type? ";
if (!(cin >> i)) { // error checking is important
cout << "Not a number, abort!\n";
return 1;
}
std::vector<int> numbers(i);
cout << "Enter the numbers: \n";
for (int a = 0; a < i; ++a)
cin >> numbers[a];
考虑如果您创建的这个数组需要在创建它的函数的作用域之外继续存在会发生什么。例如,如果这不是 main()
函数,而是 returns 到 main 的内存。或者您可能无法提前知道要创建多少个对象。例如,您可以维护基于动态实时数据的树或基于图形的数据结构。
在您给出的简单示例中,您是正确的:在堆上动态分配数组可能是一种浪费,如果做得不好,很容易导致内存泄漏等问题(尽管有一些解决方法,例如使用现代 RAII 技术进行所有分配)。但如果有动态内存可用,更复杂的场景会变得简单得多。