Reputation:
I came up with a clever (or stupid) design pattern. In one of our use cases, there might be the need to create one large memory buffer that would be used over and over for the lifetime of the class instance. In the case that we don't need the memory buffer, I'd like to avoid creating it. So I came up with the following:
class Class {
public:
void func()
{
if (A) {
// do something
} else if (B) {
// need data buffer, which we will recycle
static float * data = new float[1000000];
// do something with the data
} else {
...
}
}
~Class() {
// to delete[] or not to delete[] that is the question
}
}
Is there a way to deallocate this buffer in the destructor? I can use delete[]
, but the question is: how do we know if we have to delete the buffer? In other words, is there a clever way to know if if (B)
was executed? Of course I can do this with flags, but I wasn't sure if there was a better way to do it. The concept of a static memory buffer on the heap that may or may not be initialized is sort of confusing to me.
Upvotes: 0
Views: 178
Reputation: 41100
You could allow data
to exist in the class, but default its value to NULL
. When you delete []
it, it will be a nop
if it was not allocated.
If you're using C++11, use nullptr
instead of NULL
, as it is safer (because nullptr
does not convert to integral type, and NULL
is usually defined as 0
)
Alternatively, create data
as a vector<float> data
instead of a float*
, and you don't need to do anything in the destructor. You're not really wasting any memory if you never add anything to the vector. (Thanks Manu343726 and Malloc)
Upvotes: 6
Reputation: 4387
Embrace std::vector
#include <iostream>
#include <vector>
class Class {
public:
void func(bool test)
{
if (test) {
data_.resize(1000000);
}
}
~Class() {
std::cout << "Destroying data of size: " << data_.size() << std::endl;
}
private:
std::vector<float> data_;
};
int main() {
Class A;
Class B;
A.func(true);
B.func(false);
}
This prints:
Destroying data of size: 0
Destroying data of size: 1000000
Upvotes: 1
Reputation: 25505
You could also defer all this logic to vector. When your class is destructed the vector destructor will take care of all cases. In general vector is an acceptable solution to buffers.
class Class {
public:
void func()
{
if (A) {
// do something
} else if (B) {
// need data buffer, which we will recycle
MyVector.resize(1000000,0.0);
// do something with the data
} else {
...
}
}
private:
vector<float> MyVecto_;
}
}
Upvotes: 0