具有给定内存的c ++向量构造

我想使用std :: vector来控制给定的内存。首先,我很确定这不是一个好习惯,但好奇心对我来说更好,我想知道如何做到这一点。 我遇到的问题是这样的方法:
vector<float> getRow(unsigned long rowIndex)
{
    float* row = _m->getRow(rowIndex); // row is now a piece of memory (of a known size) that I control
    vector<float> returnValue(row, row+_m->cols()); // construct a new vec from this data
    delete [] row; // delete the original memory 
    return returnValue; // return the new vector 
}
_m是一个DLL接口类,它返回一个float数组,调用者负责删除。所以我想将它包装在一个向量中并将其返回给用户....但是这个实现为向量分配新的内存,复制它,然后删除返回的内存,然后返回向量。 我想要做的是直接告诉新的向量它可以完全控制这块内存,所以当它被删除时,内存被清除。 更新:这个的原始动机(从DLL返回的内存)被一些响应者相当牢固地压扁了:)但是,我还是想知道这个问题的答案...有没有办法构建一个std :: vector使用给定的一块预先分配的内存T *数组,以及这个内存的大小?     
已邀请:
Vector的默认分配器不提供对其内部的这种类型的访问。您可以使用自己的分配器(向量的第二个模板参数)来完成它,但这会改变向量的类型。 如果你可以直接写入向量会更容易:
vector<float> getRow(unsigned long rowIndex) {
  vector<float> row (_m->cols());
  _m->getRow(rowIndex, &row[0]);  // writes _m->cols() values into &row[0]
  return row;
}
请注意,&amp; row [0]是一个浮点*,并且保证向量可以连续存储项目。     
显而易见的答案是使用自定义分配器,但是您可能会发现这确实是您需要的重量级解决方案。如果你想这样做,最简单的方法是通过实现定义分配器(作为vector&lt;>的默认scond模板参数),复制它并使其按要求工作。 另一种解决方案可能是定义vector的模板特化,定义尽可能多的接口,并实现内存定制。 最后,如何使用一致的STL接口定义自己的容器,定义随机访问迭代器等。这可能非常容易,因为底层数组将很好地映射到vector&lt;>,并且指向它的指针将映射到迭代器。 评论UPDATE:“有没有办法使用给定的一块预先分配的内存T *数组构建一个std :: vector,以及这个内存的大小?” 当然,这里简单的答案是“不”。如果您希望结果是向量&lt;>,那么它必须支持按需增长,例如通过reserve()方法,并且对于给定的固定分配是不可能的。所以真正的问题是:你究竟想要实现什么?可以像vector&lt;>那样使用的东西,或者在某种意义上确实需要的东西是一个向量,如果是这样,那是什么意思呢?     
这里要知道的最重要的事情是不同的DLL /模块具有不同的堆。这意味着从DLL中分配的任何内存都需要从该DLL中删除(这不仅仅是编译器版本或
delete
delete[]
或其他问题)。不要通过DLL边界传递内存管理责任。这包括在dll中创建一个
std::vector
并返回它。但它还包括将一个
std::vector
传递给DLL以由DLL填充;这样的操作是不安全的,因为你不确定
std::vector
在填充值时不会尝试某种类型的调整。 有两种选择: 为
std::vector
类定义自己的
allocator
,该类使用保证驻留在创建向量的DLL /模块中的分配函数。这可以通过动态绑定轻松完成(也就是说,使
allocator
类调用一些虚函数)。由于动态绑定将在函数调用的vtable中查找,因此可以保证它将落在最初创建它的DLL /模块的代码中。 不要将向量对象传递给DLL或从DLL传递。例如,您可以使用函数
getRowBegin()
getRowEnd()
返回行数组中的迭代器(即指针)(如果它是连续的),并让用户将其作为自己的本地
std::vector
对象。你也可以反过来做,将迭代器begin()和end()传递给像
fillRowInto(begin, end)
这样的函数。 这个问题是非常真实的,尽管许多人在不知情的情况下忽视它。不要低估它。我个人遭遇了与此问题相关的无声错误,并不是很漂亮!我花了几个月才解决它。 我已经检查了源代码,并且
boost::shared_ptr
boost::shared_array
使用动态绑定(上面的第一个选项)来处理这个..但是,它们不能保证是二进制兼容的。尽管如此,这可能是一个稍微好一点的选择(通常二进制兼容性比模块内存管理要小得多)。     
你最好的选择可能是
std::vector<shared_ptr<MatrixCelType>>
。 这个帖子中有更多细节。     
如果您尝试更改向量分配/重新分配/释放内存的位置/方式,则向量类的allocator模板参数就是您要查找的内容。 如果您只是想避免构造,复制构造,赋值和销毁的开销,那么允许用户实例化向量,然后通过引用将其传递给您的函数。然后,用户负责构造和销毁。 听起来你正在寻找的是一种智能指针。一个删除它被摧毁时指向的东西。在这种情况下,查看Boost库或滚动自己的库。     
Boost.SmartPtr库包含许多有趣的类,其中一些专用于处理数组。 例如,看到scoped_array:
int main(int argc, char* argv[])
{
  boost::scoped_array<float> array(_m->getRow(atoi(argv[1])));
  return 0;
}
当然,问题在于
scoped_array
无法复制,所以如果你真的想要一个
std::vector<float>
,那么@Fred Nurk可能是你能得到的最好的。 在理想的情况下,你想要相当于
unique_ptr
但是以数组形式,但我不认为它是标准的一部分。     

要回复问题请先登录注册