Hey all,

(Skip down till "Question:" if you're in a rush)

Context: I'm coding on an audio application which involves storing buffers of audio. I'm currently using a std::vector<float> , as a member of an AudioBuffer class.

These AudioBuffer instances are held in another class ResourceHolder .

In the "process" callback (where I want to use the buffers) im doing like so:

AudioBuffer* audioBuffer   = resourceHolder->getAudioBufferPointer();
std::vector<float>* vector = audioBuffer->getVectorPointer();

// blah blah, read the vector
x = vector->at(0);

This all works ok, its only when the vector get reallocated in memory (due to another thread loading a different sample into it) that I get vector.size() back as 0.

The AudioBuffer destructor is *not* being called, so the vector isn't destructed.

Question: I want to detect when an std::vector<> gets reallocated in memory, to print its size before & after, to check if it actually contains what I expect it to.
How does one go about this..?

Cheers, -Harry

This is a really weird error, and I'm sure there is something you are not telling us. My guess would be that the audioBuffer gets relocated.

The fact that you reallocate or change the std::vector member (I assume is held by value in audioBuffer, as it should) should not cause your pointer to it to be wrong. That's simply impossible in C++. The only way that is possible is if the audioBuffer object gets relocated, which would relocate the std::vector member along with it.

You will need to post more details about the implementation of ResourceHolder and AudioBuffer, because the error cannot be diagnosed from this simple description. One thing for sure, it is not a problem about the std::vector object somehow relocating itself, objects cannot do that in C++, because of value-semantics, objects are only relocated (moved or copied) when their owner (parent object) gets moved.

Generally, it is bad practice to "export" a pointer to a data member from an object. That's dangerous code because you can never be sure that the data member still exist or is still at the same place in memory. Find an alternative. Also, rely on you compiler to optimize things, for example, there is no advantage to do this:

AudioBuffer* audioBuffer   = resourceHolder->getAudioBufferPointer();
std::vector<float>* vector = audioBuffer->getVectorPointer();

// blah blah, read the vector
x = vector->at(0);
// use the vector again and again.

Compared to doing this:

// blah blah, read the vector
x = resourceHolder.getAudioBufferPointer().getVectorPointer().at(0);
// use the vector again and again.

Assuming that you return things by reference.

Don't abuse pointers, especially raw pointers (as opposed to smart pointers). They are dangerous because they are ambiguous about ownership. Prefer to hold by value, and if you need to provide access to data members, do so by reference.

Edited 5 Years Ago by mike_2000_17: n/a

Comments
Good advice, clearly worded

Hi Mike,

Thanks for the reply, that was very helpful. Indeed you comment on the compiler optimizations is very true, the code posted is for explanatory reasons :) Thanks for the tip never the less.

Could a resizing of the std::vector cause the whole AudioBuffer object to be relocated? That would be a reasonable explaination for the bugs I'm having, and seems possible from here..

Most of all, thanks for taking the time to advise about the design aspect. I'm aware of using references rather than pointers is cleaner in certain circumstances, but I've never done this in practice. I will dig out my C++ reference, and some tutorials online.

If you have any good resource on program design that show / recommend using references over pointers, I'd be very intrested to hear where I can get it!
Cheers, -Harry

This is a really weird error, and I'm sure there is something you are not telling us. My guess would be that the audioBuffer gets relocated.

The fact that you reallocate or change the std::vector member (I assume is held by value in audioBuffer, as it should) should not cause your pointer to it to be wrong. That's simply impossible in C++. The only way that is possible is if the audioBuffer object gets relocated, which would relocate the std::vector member along with it.

You will need to post more details about the implementation of ResourceHolder and AudioBuffer, because the error cannot be diagnosed from this simple description. One thing for sure, it is not a problem about the std::vector object somehow relocating itself, objects cannot do that in C++, because of value-semantics, objects are only relocated (moved or copied) when their owner (parent object) gets moved.

Generally, it is bad practice to "export" a pointer to a data member from an object. That's dangerous code because you can never be sure that the data member still exist or is still at the same place in memory. Find an alternative. Also, rely on you compiler to optimize things, for example, there is no advantage to do this:

AudioBuffer* audioBuffer   = resourceHolder->getAudioBufferPointer();
std::vector<float>* vector = audioBuffer->getVectorPointer();

// blah blah, read the vector
x = vector->at(0);
// use the vector again and again.

Compared to doing this:

// blah blah, read the vector
x = resourceHolder.getAudioBufferPointer().getVectorPointer().at(0);
// use the vector again and again.

Assuming that you return things by reference.

Don't abuse pointers, especially raw pointers (as opposed to smart pointers). They are dangerous because they are ambiguous about ownership. Prefer to hold by value, and if you need to provide access to data members, do so by reference.

>>Could a resizing of the std::vector cause the whole AudioBuffer object to be relocated?

No. Absolutely not. You can eliminate that possibility, and look for another cause. Post more code on the context of the problem, and we might help.

>>If you have any good resource on program design that show / recommend using references over pointers, I'd be very intrested to hear where I can get it!

Well you can look at this FAQ. But, other than that, I don't know.

I've actually been preparing a tutorial on a subject very closely related to this ("avoiding memory problems by design"), as a consequence of doing a code-review on a library with many such problems. Hopefully it will be able to complete it, and post it on this forum, sometime soon.

Hi,

So I've read around on references, its a pretty basic concept really. I'll agree with you that it is better to export a reference to the array from the class, but I think its still quite ugly by design, as it exposes the internals of the class externally. (Not that my previous pointer design didn't do this, it was a hack to make it work temporarily, now I want to get it right.)

I find it quite difficult to find resources for program design, especially for the real-time domain I'm doing work in. As you've mentioned "avoiding memory problems by design", perhaps I could do a proof read of the tutorial if that suits you?

I'll be pondering the issue for the next while anyway, if I come to any reasonable conclusion I'll post back here, -Harry

>>Could a resizing of the std::vector cause the whole AudioBuffer object to be relocated?

No. Absolutely not. You can eliminate that possibility, and look for another cause. Post more code on the context of the problem, and we might help.

>>If you have any good resource on program design that show / recommend using references over pointers, I'd be very intrested to hear where I can get it!

Well you can look at this FAQ. But, other than that, I don't know.

I've actually been preparing a tutorial on a subject very closely related to this ("avoiding memory problems by design"), as a consequence of doing a code-review on a library with many such problems. Hopefully it will be able to complete it, and post it on this forum, sometime soon.

> its only when the vector get reallocated in memory (due to another thread loading a different sample into it)

The memory buffer held by the vector could get reallocated.

You need to synchronize access to the vector across multiple threads.

You need to synchronize access to the vector across multiple threads.

Indeed. And that's all taken care of using lock free ring buffers, the issue was the contents of buffers going AWOL.

Although the initial question "how to detect std::vector<>'s being relocated" remains valid I've changed the design to work around this problem.

Thanks for the replies, -Harry

>>As you've mentioned "avoiding memory problems by design", perhaps I could do a proof read of the tutorial if that suits you?

I finished the tutorial now, and you can read it here if still interested.

>>As you've mentioned "avoiding memory problems by design", perhaps I could do a proof read of the tutorial if that suits you?

I finished the tutorial now, and you can read it here if still interested.

Hell yes. Thank you for posting back :)

This question has already been answered. Start a new discussion instead.