【发布时间】:2014-10-24 17:21:51
【问题描述】:
假设我有一个函数可以将数据输入标准向量:
void getData(std::vector<int> &toBeFilled) {
// Push data into "toBeFilled"
}
现在我想将此数据发送到另一个函数,完成后应该释放数据:
void useData(int* data)
{
// Do something with the data...
delete[] data;
}
这两个函数(getData 和 useData)都是固定的,不能更改。这在复制数据一次时效果很好:
{
std::vector<int> data;
getData(data);
int *heapData = new int[data.size()];
memcpy(heapData, data.data(), data.size()*sizeof(int));
useData(heapData);
data.clear();
}
但是,这个 memcpy 操作代价高昂,并不是真正需要的,因为数据已经在堆上。是否可以直接提取和使用标准向量分配的数据?类似(伪代码):
{
std::vector<int> data;
getData(data);
useData(data.data());
data.clearNoDelete();
}
编辑:
这个例子可能没有太多意义,因为可以在函数调用 useData 之后释放向量。但是,在真实的代码中,useData并不是一个函数,而是一个接收数据的类,而且这个类的寿命比vector长……
【问题讨论】:
-
恐怕你做不到。没有释放它的内存就无法清空向量......
-
这是什么疯狂的API?!
-
@LightnessRacesinOrbit 对此 +1,这是肯定的。 Jan,您不知道数据在堆上。该标准仅要求它是连续且可随机访问的(以及其他一些内容)。像
std::string一样,对于具有合理的小对象静态缓冲区的小项目计数向量来说,这并不是闻所未闻的,一旦该页面被认为太小,就会诉诸全动态。在您寻求的用途的支持下,这样的实现会严重崩溃。 -
好吧,你总是可以 new() 那个向量,这样它的析构函数就不会被隐式调用。我认为图像足够大,可以排除向量数据的堆栈分配。我还假设(但需要验证)useData() 的 delete[](我假设)与 std::vector 的分配兼容。但是,永远不能调用向量的析构函数,因为它会再次尝试释放该内存。因此,动态分配的向量将是内存泄漏。如果您每秒调用 useData() 26 次,这可能会成为问题。
-
@WhozCraig:当前标准不允许“小向量优化”,因为移动操作不得使迭代器无效,并且移动小向量需要复制。
标签: c++ c++11 vector std stdvector