c++ - 我应该在这个程序中使用静态还是动态内存分配?
问题描述
我正在编写一个程序来获取所有素数到一个数字 n(输入)。
现在在这个程序中,我使用了静态存储分配,int arr[n+1]
但是我的编译器在编译期间不知道 n 的值(n
由用户作为输入提供),因此不知道应该分配多少空间。
应该在这个程序中使用动态存储分配吗?
int *arr=new int[n+1]
但是,该程序在这两种情况下都运行良好。
我只是想知道为什么我的程序在静态存储分配的情况下运行良好,即使n
在编译期间是未知的并且编译器不知道应该分配多少存储。
void prime(int n) {
int arr[n + 1]; // <=======
for (int i = 0; i < n + 1; i++) {
arr[i] = 1;
}
for (int i = 2; i <= n; i++) {
for (int j = 2 * i, l = 0; j < n + 1; j = (2 + l) * i, l++) {
arr[j] = 0;
}
}
for (int i = 2; i < n + 1; i++) {
if (arr[i] == 1) {
cout << i << " ";
}
}
}
int main() {
int n;
cin >> n;
prime(n);
}
解决方案
这个
void prime(int n) {
int arr[n + 1]; // <=======
不是静态分配。这是一个动态堆栈分配,它被称为可变长度数组。即使所有(大多数?)编译器都接受这样的代码,但 C++ 不允许这样做。有关更多信息,请在此处阅读:为什么可变长度数组不是 C++ 标准的一部分?
无论如何,经验法则是:当(a)您需要某个对象“长时间”生存(即比函数调用本身更长)或(b)您需要大量内存或(c)您有变量时,请使用动态堆分配长度集合(即使仍然有动态分配堆栈内存的方法,例如alloca,我认为它是一种微优化并且难以使用 - 如果可能,请避免使用)。
您也可能想利用std::vector。它在后台也使用动态堆分配,但通常比手动更安全new/delete
。
推荐阅读
- laravel - 404 在生产中导航到 laravel 中的获取路线时
- python - 在命令行中将多个 xml 文件一起添加
- swift - 在 macOS 中将 WKWebView 内容转换为 PDF
- javascript - 从插件向用户显示警告(非错误)消息
- google-cloud-storage - 谷歌云存储中的 Avro 与 Parquet 使用谷歌数据流转换
- android - Android - onClickListener NullPointerException
- ruby - 如何在mongodb中连接2个不同的主机
- c++ - 针对编译时常数优化的函数
- swift - 根据数组中的值替换字符串中的多个单词
- c++ - C++ 指针返回意外值