【发布时间】:2011-06-18 08:20:15
【问题描述】:
我想使用 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 接口类,它返回一个浮点数组,调用者负责删除该数组。所以我想把它包装在一个向量中并将其返回给用户......但是这个实现为向量分配新内存,复制它,然后删除返回的内存,然后返回向量。
我想做的是直接告诉新向量它可以完全控制这块内存,所以当它被删除时,内存就会被清理掉。
更新:最初的动机(从 DLL 返回的内存)已被许多响应者相当坚决地压制 :) 但是,无论如何,我很想知道这个问题的答案...有没有办法使用给定的预分配内存 T* 数组块和该内存的大小来构造 std::vector?
【问题讨论】:
-
如果内存是用
new[]或malloc分配的,当您调用delete row时,发布的代码会导致未定义的行为 -
@Jamie Cook:好的,那么您的 DLL 接口是否具有分配和释放内存的功能? DLL 接口应该具有用于内存管理的对称函数,因为您不能保证从
getRow()返回的数组甚至可以被delete[]删除。您应该将getRow()重命名为copyRow()之类的名称,并创建一个名为deleteRow()之类的函数,然后提供createRowArray()之类的名称,以便vector可以增加其容量。 -
不要不让您的 DLL 分配您负责解除分配的内存,这可能会导致难以追踪的内存损坏错误。请参阅blogs.msdn.com/b/oldnewthing/archive/2006/09/15/755966.aspx 以获得更详细的解释(简短回答:不同的 DLL/模块可以加载不同版本的 C/C++ 运行时)。
-
@Jamie Cook:下面是我所说的一个例子:
GetWindowTextLength()和GetWindowText()是在 Windows API 中检索窗口标题的两个函数。应用程序调用GetWindowTextLength()分配一个足够大的缓冲区,然后传递缓冲区指针GetWindowText()允许函数用文本填充它。你应该这样设计你的 DLL 接口。那么根据这两个函数创建一个方便函数就变得很容易了。 -
@ChrisLutz:_m 仅在全局范围内保留。 不是“所有以下划线开头的名称”都是保留的。我怀疑这个 _m 是一个数据成员。 (如果它不是数据成员,那么如果它在命名空间中,它仍然可能不会被保留。)
标签: c++ memory-management vector