我正在将双向量转换为双倍数组,如here所示:
不同之处在于,我想将指针a作为函数参数返回:
void getArray(double* a)
{
std::vector<double> v;
a = &v[0];
}
所以我的问题是,a
的内存何时被解除分配?或者我必须自己调用delete[] a
,这似乎很奇怪,因为我没有用new
分配内存。我已经阅读了上述答案的评论,但我仍然不清楚。
答案 0 :(得分:6)
a
指向的内存在导向v
被解构时被释放。在这种情况下,这就是函数getArray
的末尾。
答案 1 :(得分:1)
不要这样做:
void getArray(double* a)
{
std::vector<double> v;
a = &v[0];
} // The vector is destroyed here, and the memory
// is deallocated.
在任何情况下,您都不会在功能之外修改a
指针,因此您无法获得所需的效果。
相反,请返回vector
并直接使用它。或者,通常,在整个代码中使用向量。如果需要将 in 传递给期望指向数组的指针的函数,可以在那里传递&v[0]
。这样的功能通常也需要大小。为此,通过v.size()
。只要该功能不占用所有权或取消分配内存,您就可以安全地执行此操作。
另请注意,声明为std::vector<double> v;
的向量没有大小,因此尝试访问第一个元素(如v[0]
中)也是未定义的行为。至少,您需要给向量一个大小(将大小传递给它的构造函数)以确保分配一些内存。在索引之前,你应该总是确保向量有一些已分配的内存,包括在尝试获取第一个元素的地址时。
您可能想要做的是:
std::vector<double> getArray() {
std::vector<double> v = /* some sane initialisation */;
return v;
}
// some time later, assuming a function:
// void do_something(double* a, size_t n);
// ...
std::vector<double> v = getArray();
if (v.size()) {
do_something(&v[0], v.size());
} else {
// fail gracefully
}
答案 2 :(得分:1)
此实现将调用未定义的行为,因为v
是本地的:
void getArray(double* a)
{
std::vector<double> v;
a = &v[0]; // would be a UB for returning the pointer to internals of a local variable.
}
但是,调用者永远不会看到任何效果,因为对a
的修改保持在getArray
函数的本地。
如果要从向量中创建数组,请分配新数组,使用std::copy
将内容复制到其中,然后将数组返回给调用者。确保调用者在完成copyL
delete[]
double *getArray(const vector<double>& v) {
double *res = new double[v.size()];
std::copy(v.begin(), v.end(), res);
return res;
}
调用者应按如下方式使用它:
vector<double> data;
data.push_back(...);
... // populate the vector
double *tmp = getArray(data);
... // Use the array
delete[] tmp; // Avoid memory leaks
答案 3 :(得分:1)
a的内存何时被解除分配?
a
指针本身是一个局部变量,所以它在其范围的末尾被释放。
a
指向向量v
分配的内存。指向的内存在v
的析构函数中被释放(如果向量被添加到向量中或从向量中移除,则也可以释放内存)。因为v
是一个局部变量,所以它在范围的末尾被销毁。
或者我必须自己打电话给删除[],
不,因为内存由vector对象拥有,但也因为
这看起来很奇怪,因为我没有用新的分配内存。
完全。您没有致电new[]
,因此请勿致电delete[]
。
请注意,v[0]
具有未定义的行为,因为向量为空。