1

Bit of a basic question. Say I've defined a multi-dimensional array as follows:

#include <vector>
using std::vector;

#define HEIGHT 5
#define WIDTH  3

// Define vector
vector<vector<int> > array2D;

// Set up size
array2D.resize(HEIGHT);
for (int i = 0; i < HEIGHT; i++)
  array2D[i].resize(WIDTH);

// Put some values in
array2D[1][2] = 6;
array2D[4][1] = 5;

Now I want to re-use the array or explicitly clean up memory. Do I just call array2D.clear(); (which will hopefully automatically clean up the rows) or must I first explicitly clear each row?

// Option 1: Is this sufficient?
array2D.clear();

// Option 2: Or do I need to explicitly clear each row:
for (int i = 0; i < HEIGHT; i++)
  array2D[i].clear();

array2D.clear();

Note: The vector could be made to go out of scope, but ideally I'd like to hold the vector as a class member and only resize and re-use when the dimensions change. This will be very rare.

AlainD
  • 5,413
  • 6
  • 45
  • 99
  • 2
    calling clear on the outer vector will delete all inner vectors. This is actually pretty inefficient if you plan to reuse the vector. – Richard Hodges Jan 16 '18 at 10:54
  • Let it go out of scope. – erip Jan 16 '18 at 10:56
  • @RichardHodges: Why is it inefficient? The vector is intended to be held as a class member and only re-used if dimensions change (which will be rare). – AlainD Jan 16 '18 at 11:04
  • 1
    @erip: Thanks, I know I can let it go out of scope but that's not the question. – AlainD Jan 16 '18 at 11:06
  • @AlainD You haven't written anything in your question that suggests that letting it go out of scope isn't acceptable... – erip Jan 16 '18 at 11:06
  • 1
    If you need to free up the memory, you can clear it. If you just want to reuse it, more efficient to just resize the vectors. (repeat your set up size step) – super Jan 16 '18 at 11:08
  • 2
    @AlainD because clear()ing the outer vector will destruct all the inner ones, which means they'll release their memory back to the heap. So if you plan to reuse the vector of vectors, you'll have to re-create the inner vectors, which will result in more allocations. – Richard Hodges Jan 16 '18 at 11:09
  • @erip: Yes, that is true, good observation. The question has been modified to indicate the reasons for wanting to re-use the vector. – AlainD Jan 16 '18 at 11:24
  • C++ has poor support for multi-dimensional arrays. If you are doing anything significant with them then I'd recommend using a library like eigen http://eigen.tuxfamily.org/index.php?title=Main_Page. – Paul Floyd Jan 16 '18 at 11:25
  • 2
    As to efficiency - if this is a matter, mapping the two dimensions into a single one-dimensional array/vector (and providing appropriate accessors) might be an alternative... – Aconcagua Jan 16 '18 at 11:57

1 Answers1

1
std::vector<std::vector<int>> v(H, std::vector<int>(V));
...
v.clear();

This will destroy all the inner vectors and therefore release their buffers. If you want to reuse v with different sizes, you might better write something as:

v.resize(NEW_H);
for (auto & inner_v : v)
  inner_v.resize(NEW_V);

By using C++11, which can be easily written in C++03 with ordinary loop.

For really efficient resizing, you may also want to set the capacity of both the outer vector and all the inner vectors in advance.

Also note that if you want to release vector buffer explicitly, clear does not do that alone. In C++11 there is shrink_to_fit member function for this, in C++03 you have to swap with empty vector.

Daniel Langr
  • 22,196
  • 3
  • 50
  • 93
  • What does "swap with empty vector" mean? – AlainD Jan 16 '18 at 11:28
  • @AlainD `swap` exchanges the contents of two vectors. So if you use `v.swap(e)` or `std::swap(v, e)`, where `v` is your vector and `e` is an empty one (meaning `capacity() == 0` , *not* `size() == 0`), you clear your vectors *capacity*. – Aconcagua Jan 16 '18 at 11:44
  • @AlainD Such swapping is typically done with a temporary empty vector. See, e.g., this answer for more details: https://stackoverflow.com/a/10465032/580083 – Daniel Langr Jan 16 '18 at 12:07
  • C++11 is not a "dialect". – Christian Hackl Jan 16 '18 at 14:37
  • @ChristianHackl Thanks for clarification. I am not a native speaker, so some of these subtleties are a bit confusing for me, since I've hard this multiple times (e.g., Google founds over 1000 matches with "C++11 dialect"). – Daniel Langr Jan 16 '18 at 15:23