将向量转换为数组.如何处理内存

Converting vector to array. How to deallocate memory?

本文关键字:处理 内存 何处理 向量 转换 数组      更新时间:2023-10-16

我正在将双打向量转换为双打数组,如下所示:

区别是,我想返回指针A作为函数参数:

void getArray(double* a)
{
    std::vector<double> v;
    a = &v[0];
}

所以我的问题是,a的内存何时被划定?还是我必须自己打电话给delete[] a,这似乎很奇怪,因为我没有将内存分配给new。我已经阅读了上述答案的评论,但我仍然不清楚。

当vector v破坏时,由 a指向的内存将被划分。在这种情况下,这是函数 getArray的末尾。

此实现将调用未定义的行为,因为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将内容复制到其中,然后将数组返回给呼叫者。确保呼叫者使用葡萄干完成后调用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

不要这样做:

void getArray(double* a)
{
    std::vector<double> v;
    a = &v[0];
} // The vector is destroyed here, and the memory
  // is deallocated.

无论如何,您不会在功能之外修改a指针,因此您不会获得所需的效果。

而是返回vector并直接使用它。或者,通常,在整个代码中使用向量。如果您需要将它们传递给中的到期望指向数组的指针的函数,则可以在那里传递&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
}

什么时候被交易?

a指针本身是局部变量,因此在其范围结束时进行交易。

a指向向量v分配的内存。在v的破坏者中划分尖的内存(如果将对象添加到向量或从矢量中删除,也可以对内存进行处理)。而且由于v是局部变量,因此在范围的末端被破坏。

或我必须自己打电话给delete [] a

no,因为内存是矢量对象拥有的,也是因为

这似乎很奇怪,因为我没有将内存分配给新的。

准确。您没有致电new[],所以您不致电delete[]


请注意,v[0]的行为不确定,因为向量是空的。