C++:如何安全地解除分配堆分配的向量数组?
C++ : How to safely deallocate a heap-allocated array of vectors?
我目前正在使用的代码目前需要我制作一个向量数组(我是 C++ 的新手 - 如果这是一个绝对糟糕的想法,我将非常感谢您的反馈)。
假设我像这样在堆上为我的向量分配内存:
#include <iostream>
#include <vector>
#include <random>
int main() {
typedef std::vector<double> doubleVec;
long N = 1000;
long M = 1000;
doubleVec *array = new doubleVec[N];
for (long i = 0; i < N; i++) {
doubleVec currentVec = array[i];
currentVec.resize(M);
for (long j = 0; j < M; j++)
currentVec[j] = std::rand();
}
// ... do something with the data structure
delete [] array;
}
当我对数据完成所有需要做的事情后,我应该如何安全地释放这个数据结构?
注意: 我在最初的 post 中还做错了一些我不打算做的事情讨论的焦点(未初始化的变量,未调整向量的大小等)。我现在修好了。谢谢大家指出。
问题不在解除分配中,而是在每个向量分配中。您在代码中的什么地方使用了 M
值(访问元素时除外)?您的代码中还有其他问题,因此快速修复是:
for (long i; i < N; i++) {
doubleVec ¤tVec = array[i];
currentVec.resize(M);
for (long j; j < M; j++)
currentVec[j] = std::rand();
}
请特别注意 currentVec
是引用:否则不会在 array
.
中存储任何更改
无论如何,每个人的主要问题是:为什么需要向量数组?..向量的向量是一个更优雅的解决方案。
更新:我没有注意到您忘记初始化 i
和 j
。除了初始化它们的建议之外,我还建议使用 auto
关键字,这样就不可能让变量保持未初始化状态:
for (auto i=0UL; i < N; i++) {
doubleVec ¤tVec = array[i];
currentVec.resize(M);
for (auto j=0UL; j < M; j++)
currentVec[j] = std::rand();
}
0UL
表示 unsigned long 类型的零。
f this is an absolutely terrible idea, I would greatly appreciate the feedback).
是的,这是一个非常糟糕的主意。具体来说,拥有裸指针不是一个好主意。与其手动分配动态数组,不如使用 std::vector
.
这样的容器通常更好
How to safely deallocate a heap-allocated array of vectors?
通过使用向量而不是手动动态数组。在这种情况下,一个简单的解决方案是使用向量的向量。
一个可能更好的解决方案是分配一个大小为 1000*1000 的双精度平面向量,其中每个“子向量”的元素一个接一个。这需要一些简单的数学运算来计算子向量的索引,但在大多数用例中速度更快。
其他说明:
typedef std::vector<double> doubleVec;
通过像这样隐藏类型名称来避免混淆程序。
for (long j; j < M; j++)
^^^^^^
您未初始化此变量。以后使用不确定值时,程序的行为是不确定的。
此外,您忘记包含定义 std::vector
和 std::rand
的标准 headers。
I got a seg fault
请参阅其他答案,了解您实际上并未向数组中的向量添加任何元素。这和未初始化的变量是您段错误的最可能原因,具体取决于“做某事”的作用。
我目前正在使用的代码目前需要我制作一个向量数组(我是 C++ 的新手 - 如果这是一个绝对糟糕的想法,我将非常感谢您的反馈)。
假设我像这样在堆上为我的向量分配内存:
#include <iostream>
#include <vector>
#include <random>
int main() {
typedef std::vector<double> doubleVec;
long N = 1000;
long M = 1000;
doubleVec *array = new doubleVec[N];
for (long i = 0; i < N; i++) {
doubleVec currentVec = array[i];
currentVec.resize(M);
for (long j = 0; j < M; j++)
currentVec[j] = std::rand();
}
// ... do something with the data structure
delete [] array;
}
当我对数据完成所有需要做的事情后,我应该如何安全地释放这个数据结构?
注意: 我在最初的 post 中还做错了一些我不打算做的事情讨论的焦点(未初始化的变量,未调整向量的大小等)。我现在修好了。谢谢大家指出。
问题不在解除分配中,而是在每个向量分配中。您在代码中的什么地方使用了 M
值(访问元素时除外)?您的代码中还有其他问题,因此快速修复是:
for (long i; i < N; i++) {
doubleVec ¤tVec = array[i];
currentVec.resize(M);
for (long j; j < M; j++)
currentVec[j] = std::rand();
}
请特别注意 currentVec
是引用:否则不会在 array
.
无论如何,每个人的主要问题是:为什么需要向量数组?..向量的向量是一个更优雅的解决方案。
更新:我没有注意到您忘记初始化 i
和 j
。除了初始化它们的建议之外,我还建议使用 auto
关键字,这样就不可能让变量保持未初始化状态:
for (auto i=0UL; i < N; i++) {
doubleVec ¤tVec = array[i];
currentVec.resize(M);
for (auto j=0UL; j < M; j++)
currentVec[j] = std::rand();
}
0UL
表示 unsigned long 类型的零。
f this is an absolutely terrible idea, I would greatly appreciate the feedback).
是的,这是一个非常糟糕的主意。具体来说,拥有裸指针不是一个好主意。与其手动分配动态数组,不如使用 std::vector
.
How to safely deallocate a heap-allocated array of vectors?
通过使用向量而不是手动动态数组。在这种情况下,一个简单的解决方案是使用向量的向量。
一个可能更好的解决方案是分配一个大小为 1000*1000 的双精度平面向量,其中每个“子向量”的元素一个接一个。这需要一些简单的数学运算来计算子向量的索引,但在大多数用例中速度更快。
其他说明:
typedef std::vector<double> doubleVec;
通过像这样隐藏类型名称来避免混淆程序。
for (long j; j < M; j++) ^^^^^^
您未初始化此变量。以后使用不确定值时,程序的行为是不确定的。
此外,您忘记包含定义 std::vector
和 std::rand
的标准 headers。
I got a seg fault
请参阅其他答案,了解您实际上并未向数组中的向量添加任何元素。这和未初始化的变量是您段错误的最可能原因,具体取决于“做某事”的作用。