1

I'm developing a class to read a WAV file. The class should produce a vector for each channel (left/right), with the channel vectors in a vector of their own.

I've defined the loading method in the class as:

std::vector<std::vector<double> >* wavloader::load() throw(load_failed)

hence returning a pointer to this vector of vectors.

Inside the class I've allocated the memory for the top level vector, then created vectors for as many channels as I want, as follows:

std::vector<std::vector<double> >* audio_all_chans = new std::vector<std::vector<double> >;

std::vector<double> dummy_vector;

for(int chan_index = 0; chan_index<n_channels; chan_index++)
(*audio_all_chans).push_back(dummy_vector);

I then run through the file, and fill each of the vectors with the appropriate samples.

While the top level 'vector of vectors' is assigned using new, I'm concerned that the individual 'channel' vectors (generated with the dummy_vector) are in a way allocated on the stack.

When I leave the class, will the containing vectors go out of scope and be liable to be overwritten?

The program compiles with no warning at all, valgrind is completely happy with it, and I still get correct values from the returned pointer with the class deleted, but I'm a bit concerned there could be something insidious going on!

Speedy
  • 476
  • 2
  • 13
  • If `valgrind` says that all heap memory was properly deallocated and your program compiles fine, why do you think that something would be "randomly overwritten"? – Kerrek SB Nov 20 '11 at 20:57
  • Why are you creating a dynamically-allocated vector? Have you considered wrapping it in a smart pointer? – Oliver Charlesworth Nov 20 '11 at 20:59
  • 2
    Why are you dynamically allocating a vector and then returning a pointer to it? Why not simply return the vector by value? – fredoverflow Nov 20 '11 at 20:59
  • Are the inside vectors definitely being allocated on the heap? My concern was that the inside vectors are somehow coming from the stack within the class. @KerrekSB – Speedy Nov 20 '11 at 21:00
  • @OliCharlesworth - So that it doesn't get deallocated outside the loading class. Would a smart pointer prevent this? – Speedy Nov 20 '11 at 21:03
  • @FredOverflow - I'm trying to copy a style I've seen in other libraries (VTK) whereby pointers to objects are returned. If I was to follow your suggest would I not have to return by reference? – Speedy Nov 20 '11 at 21:04
  • 2
    By the way, exception specifiers are deprecated. – Matteo Italia Nov 20 '11 at 21:35
  • Technically the new `nothrow` is still called an exception specification. It's dynamic exception specifications which are deprecated. – bames53 Nov 20 '11 at 22:56
  • 1
    @Speedy: No, returning by value does not necessarily imply a copy. Unless you're doing something really crazy in your code, it is extremely likely that RVO (return value optimization) will kick in. If it doesn't kick in, C++11 compilers are mandated to [move](http://stackoverflow.com/questions/3106110/) the result instead of doing a copy. – fredoverflow Nov 21 '11 at 06:49
  • 1
    Also, vectors *always* have their actual data (the elements that you `push_back`) on the heap, no matter how you allocate the vector object, which only consists of a couple of pointers. A stack vector has a couple of pointers on the stack and the actual data on the heap, whereas a "heap vector" has a couple of pointers on the heap and the actual data also on the heap. It is impossible for a vector to have its data on the stack, so "nested vectors" or "inside vectors" as you call them will always be on the heap. – fredoverflow Nov 21 '11 at 06:52
  • @FredOverflow - Exactly what I was after, thanks! Why not copy your last two comments as an answer? – Speedy Nov 21 '11 at 09:30

2 Answers2

1

vector inside a vector is totally safe. In here:

(*audio_all_chans).push_back(dummy_vector);

you push back a copy of the vector, not the vector itself.

Daniel
  • 30,896
  • 18
  • 85
  • 139
1

I know it is scary, but the way you did it was fine. A good rule of thumb is to look at the number of *s in your declaration, and delete that many items. So you have a pointer to a dynamically allocated vector. Good, you need to delete that.

What about inside? Well that vector held pointers to other vectors, then we would be responsible for getting rid of those, but since you just have vectors in there, they will go out of scope and be deleted.

Chris
  • 11,819
  • 19
  • 91
  • 145