Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to copy a section of a large array into a smaller one?

Tags:

c++

arrays

I have a situation where I will need an amount of memory determined at runtime to pass to a function. I am using a larger buffer on the stack, then only creating on the heap the space that is necessary:

Foo largeBuf[1024];

int sizeUsed = fillBuff(largeBuf, 1024);

Foo* smallerBuf = new Foo[sizeUsed];

for (UINT i = 0; i < sizeUsed; i++)
{
 smallerBuf[i] = largeBuf[i];
} 

Is there a better way to do this? Some standard array copying function?

like image 975
Nick Heiner Avatar asked Dec 05 '22 02:12

Nick Heiner


2 Answers

You should probably be using an std::vector, which you can initialize directly from the elements of the larger buffer:

std::vector<Foo> smallerBuf(largeBuf, largeBuf+sizeUsed);
like image 131
Jerry Coffin Avatar answered Dec 07 '22 14:12

Jerry Coffin


Firstly, you should be using std::vector. There's no reason not to use it. Then use 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));

Or just cut to the chase at the end with:

std::vector<Foo> smallerBuf(largeBuf, largeBuf + sizeUsed);

Or another approach:

std::vector<Foo> buf(1024); // this replaces your stack array
buf.resize(fillBuff(&buf[0], 1024)); // copies directly into it, resizes

Note after this last approach, the memory will still be in use. You can force the capacity to shrink with the 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);

Most ideal, fillBuf would have a way (or another function) to just return the number of elements it will return given a buffer. Then you can just do:

std::vector<Foo> buf(buffSize()); // or whatever
fillBuff(&buf[0], buf.size());
like image 32
GManNickG Avatar answered Dec 07 '22 15:12

GManNickG