我遇到一种情况,我需要在运行时确定一定量的内存以传递给函数。我在堆栈上使用更大的缓冲区,然后只在堆上创建必要的空间:
Foo largeBuf[1024];
int sizeUsed = fillBuff(largeBuf, 1024);
Foo* smallerBuf = new Foo[sizeUsed];
for (UINT i = 0; i < sizeUsed; i++)
{
smallerBuf[i] = largeBuf[i];
}
有更好的方法吗?一些标准的阵列复制功能?
答案 0 :(得分:6)
您可能应该使用std::vector
,您可以直接从较大缓冲区的元素初始化:
std::vector<Foo> smallerBuf(largeBuf, largeBuf+sizeUsed);
答案 1 :(得分:5)
首先,您应该使用std::vector
。没有理由不使用它。然后使用std::copy
:
// surely the pointer was an accident
Foo largeBuf[1024];
// int? design should be changed to use an unsigned type
int sizeUsed = fillBuff(largeBuf, 1024);
// vector, no memory leaks
std::vector<Foo> smallerBuf;
smallerBuf.reserve(sizeUsed);
// copy
std::copy(largeBuf, largeBuf + sizeUsed, std::back_inserter(smallerBuf));
或者只是切断追尾:
std::vector<Foo> smallerBuf(largeBuf, largeBuf + sizeUsed);
或另一种方法:
std::vector<Foo> buf(1024); // this replaces your stack array
buf.resize(fillBuff(&buf[0], 1024)); // copies directly into it, resizes
请注意,在最后一种方法之后,内存仍将被使用。您可以使用copy-swap trick:
强制缩小容量template <typename T, typename A>
void shrink_to_fit(std::vector<T, A>& pVector)
{
std::vector<T, A>(pVector).swap(pVector);
}
// ...
shrink_to_fit(buf);
最理想的是,fillBuf
会有一种方式(或其他函数)只返回给定缓冲区时它将返回的元素数。然后你可以这样做:
std::vector<Foo> buf(buffSize()); // or whatever
fillBuff(&buf[0], buf.size());
答案 2 :(得分:4)
一些标准的阵列复制功能? 的
你的意思是除了std :: copy()?
答案 3 :(得分:1)
我认为最快的方法是使用memcpy:
const int BUFSIZE = 1024;
Foo* largeBuf = new Foo[BUFSIZE];
int sizeUsed = fillBuff(largeBuf, BUFSIZE);
Foo* smallerBuf = new Foo[sizeUsed];
memcpy(smallerBuf, largeBuf, sizeUsed * sizeof(Foo));
如果在Windows平台上,memcpy_s会更安全:
memcpy_s(smallerBuf, sizeUsed, largeBuf, sizeUsed * sizeof(Foo));
答案 4 :(得分:0)
在C ++中,您可以使用std::copy
。如果你的函数没有修改数组,你可以传递一个const指针和一个大小而不复制数组:some_func( largeBuf, sizeUsed );
答案 5 :(得分:0)
你看到的一个习惯用法是两次拨打fillBuff
。一旦得到大小,一次到工作。 fillBuff
计算所需的缓冲区大小通常是微不足道的:
int sizeUsed = fillBuff(NULL, 0);
Foo* buffer = new Foo[sizeUsed];
fillBuff(buffer, sizeUsed);
如果情况并非如此,我建议使用矢量:
vector<Foo> buffer;
fillBuff(buffer);
或者,如果您必须分配两次,至少要指定缓冲区的大小:
Foo largeBuf[1024];
int sizeUsed = fillBuff(largeBuf, 1024);
Foo* smallerBuf = new Foo[sizeUsed];
std::copy(largeBuf, largeBuf + sizeUsed, smallerBuf);
答案 6 :(得分:0)
这种情况多久发生一次?如果这将是一个紧凑的循环,有很多不同的选择要考虑。您可以提前创建堆栈或堆,并自己进行一些内存管理。或者你可以只是传递指针并分享数据,如果你可以安全地这样做,而无需在不知不觉中进行编辑。
如果这是一个非常时间敏感的事情,那么有许多不同的实现,但如果你不需要,我会远离创建更多的对象层。如果你用零填充内存,检查malloc和设置之间的实现速度差异为0而不是calloc。或者特定于系统的东西,比如bzero(),有时会使用特定于硬件的内存命令。还要注意memcpy()vs memmove() - 确定哪一个是必要的。
有点有趣的琐事:http://en.wikipedia.org/wiki/Duff%27s_device: - )