how to redimensione (ReDim) an array in C++

Started by
7 comments, last by SeanMiddleditch 9 years, 6 months ago

how to redimensione (ReDim) an array in C++ native?

Advertisement

You don't; not directly. You use std::vector.

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

i want that without std::vector

Create a new array, copy the old data to it. If you're dealing with POD structures, you can do this with realloc. Otherwise you need to handle it manually.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Then re-implement what std::vector does or a small subset of it:

* allocate new block of memory

* move over the old values

* free the old block of memory

If you somewhy meant to resize stuff like "int array[66]" - then that is simply not possible.

i want that without std::vector

Any particular reason? std::vector doesn't do a huge amount more than this, and what it does can be incredibly useful. When it comes to adding storage, what std::vector provides is amortised constant time growth by growing exponentially.

That is, when a std::vector of size N is full, inserting another element might cause double the memory to be allocated, the first N elements are copied (or moved) and the new element is copied (or moved). Obviously, the original storage would be deallocated. This might sound undesirable, but the important point is that the next N - 1 insertions are really cheap: just copy (or move) the new element! No need to allocate, deallocate or copy the existing elements. In constrast, the naive algorithm of allocate / copy / deallocate every time you need more storage requires you to do this work each time too, which quickly adds up.

Since most insertions are not the last, std::vector's optimisation usually makes sense. In the cases it does not, you can stilluse reserve() or resize() and gain effective control over the allocations without losing the other benefits of std::vector, such as automatic memory management.


That is, when a std::vector of size N is full, inserting another element might cause double the memory to be allocated, the first N elements are copied (or moved) and the new element is copied (or moved). Obviously, the original storage would be deallocated. This might sound undesirable, but the important point is that the next N - 1 insertions are really cheap: just copy (or move) the new element! No need to allocate, deallocate or copy the existing elements. In constrast, the naive algorithm of allocate / copy / deallocate every time you need more storage requires you to do this work each time too, which quickly adds up.

Actually, many implementations (including the visual studio one) I've seen grow by 1.5x, as this is close to the golden ratio (1.618...) which is the optimal growth amount. Clang or GCC might grow by 2x though.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Clang or GCC might grow by 2x though.


Hopefully not. A 2x growth factor is not good.

Sean Middleditch – Game Systems Engineer – Join my team!

To the OP, you obviously can't resize a native array univerally. It's allocated on the stack (and other things follow it on the stack), inside a data structure (which has fixed size), or on the heap (and there may be other things after it outside your control).

You can allocate a new array and then use C++ algorithms to easily copy data to it. Unless the array is heap-allocated, though, you have no way to get rid of the old one other than letting it (or its owner) go out of scope. If you are using a heap-allocated C-style array, use std::unique_ptr.

// example old array
auto array = std::make_unique<int[]>(oldSize);

// create a new array
auto newArray = std::make_unique<int[]>(newSize);

// copy the data from the old array to the new one, accounting that size may be bigger or smaller
std::copy_n(array.get(), std::min(kSize, kNewSize), newArray.get());

// replace the old array (deallocate it) with the new one
array = std::move(newArray);
The problem you may have here is that you need to explicitly track the array size on your own. Which is why you just want a std::vector.

Note that even if you do want a C-style fixed-size array there's often reason to prefer std::array over the C-style syntax. Compile-time fixed-size arrays that can be allocated on the heap if you need:

// heap allocated 100-int array
auto array = std::make_unique<std::array<int, 100>>();
There's not a huge amount of good reason to do this instead of using std::vectory, though. There can be an argument made that you might want a data structure where size==capacity, has no implicit copy, and differentiates between being null and being empty, and saves on the size of one void*/size_t vs most std::vector, but it's not a very good argument.

Even as a high-performance game developer, just use std::vector unless you have damn good reason not too (e.g., empirical evidence that it's not performing adequately).

Sean Middleditch – Game Systems Engineer – Join my team!

This topic is closed to new replies.

Advertisement