Memory leak after pointing to NEW object - c++

struct StructA {
StructA(parameters) { ... } //StructA onstructor
};
struct StructB {
StructA *pObjectA;
int counter = 0;
void function() {
if (counter < 1) { pObjectA = new StructA[100]; }
pObjectA[counter] = *new StructA(parameters); //Memory leak here
counter++;
}
};
struct StructC {
StructB objectB;
~StructC() { //StructC destructor
delete[] objectB.pObjectA;
objectB.pObjectA = NULL;
}
};
int main() {
StructC objectC;
for (int i = 0; i < 900; i++) {
objectC.objectB.function();
}
return 0;
} //Struct C destructor here
I need to create an object array and then, with each call to objectB.function(), to pass specific parameters to the constructor of StructA. The code above works perfectly, except for the memory leak, which I am unable to get rid of.
My guess is that the StructC destructor deletes only the object array, not each *new StructA(parameters). I tried to play around with pointers and delete[] a little bit, but all I got was access memory violation errors. This is the only way I can think of that works. All help appreciated.

A class destructor should release resources that were acquired in its constructor. It seems like you wanted to defer deleting an array allocated in one class to the destructor of a second class. Thats never a good idea. In the best case you dont have to do anything in the destructor because you use automatic storage (means what the name suggest: memory is managed automatically).
Your code could look like this:
struct StructA {
StructA(parameters) { ... } //StructA onstructor
};
struct StructB {
std::vector<StructA> pObjectA;
int counter = 0;
void function() {
if (counter < 1) { pObjectA.reserve(100); }
pObjectA.emplace_back(parameters);
counter++;
}
};
struct StructC {
StructB objectB;
};
int main() {
StructC objectC;
for (int i = 0; i < 900; i++) {
objectC.objectB.function();
}
return 0;
}
Note that I tried to keep the structure as is maybe there are other things to change. For example you dont need counter, as you can use std::vector::size to query the number of elements in the vector.
PS: As you already noticed, this is a memory leak:
pObjectA[counter] = *new StructA(parameters); //Memory leak here
It is not really clear why you wrote that code in the first place. The idomatic way to create an object of type StructA is StructA a; (no new!).

As you correctly assumed, memory leaks are caused by not properly cleaning up all new with corresponsing delete. However in idiomatic C++ there's no use to use new and delete directly.
Use std::vector, std::shared_ptr and std::unique_ptr to let RAII keep track of dynamically created objects, references to them and when to clean up. Not only is it more robust, it's also a lot shorter and easier to read.
With your code's general overall structure:
#include <memory>
#include <vector>
struct StructA {
};
struct StructB {
std::vector<std::shared_ptr<StructA>> objectAs;
void function() {
objectAs.push_back(
std::make_shared<StructA>( /*parameters*/ )
);
}
};
struct StructC {
StructB objectB;
};
int main() {
StructC objectC;
for (int i = 0; i < 900; i++) {
objectC.objectB.function();
}
return 0;
}

Related

C API: Error allocating / deallocating memory for array

I'm in the process of implementing an API for C. The code base itself is purely written in C++ and I only plan to offer said interface for any consumer using C. The interface is defined in a .h file, whereas the implementation itself is written in C++. I've read multiple times that using C++ to implement a C interface is not the best idea, but it works great in my case.
Anyway the header definition looks similar to this:
extern 'C' {
typedef struct Person {
const char *name;
uint32_t age;
uint32_t post_code;
} Person;
typedef struct PersonArray {
Person *person;
size_t size;
} PersonArray;
PersonArray *create(size_t size);
void destroy(PersonArray *array);
int fillArray(PersonArray *array);
}
I'd like the consumer to retrieve a handle for PersonArray, which contains an array of Person structure, allocated with the size passed to the create() function.
Since the implementation is in C++ I've tried to allocate the memory the following way:
static inline Person convert(const otherNamespace::Person &o_person) {
Person p{};
p.name = o_person.name;
p.age = o_person.age;
p.post_code = o_person.post_code;
return p;
}
PersonArray *create(size_t size) {
if (size <= 0) {
return nullptr;
}
PersonArray *array = new PersonArray();
array->size = size;
array->person = new Person[size]
return array;
}
void destory(PersonArray *array) {
delete array;
}
int fillArray(PersonArray *array) {
if (array == nullptr) {
return 1;
}
auto data = // retrieve std::vector<otherNamespace::Person> via RPC
for (auto i{0U}; i < array->size; i++) {
array->person[i] = convert(data.at(i);
}
return 0;
}
Unfortunately, this approach does not seem to work correctly, because when using a memchecker like valgrind, there are still blocks on the heap that are not correctly deallocated. I suppose the line new Person[size] does not get deallocated.
Any idea how to fix this memory leak? Or is there another design which would be better suited for this specific use case? If possible, I would really like to keep the implementation in C++.
You must use delete on person before array, but since it was allocated with new [] you must delete it with delete [].
void destroy(PersonArray *array) {
if (array) {
if (array->person) {
delete [] array->person;
}
delete array;
}
}

How to make a temporary variable's pointer valid in the future?

I have a project, which receives data from a socket, then handles it and saves good data into a container.
I want high performance, so, i need to keep the copy operation less as i can.
here is my first code:
struct Data { // here is a demo, in real project, Data is a large struct
int a;
char b[20];
}; // data type
std::vector<const Data*> data_base;
void Handle(const Data& a) {
if (a.good()) { // only few data will get good
data_base.emplace_back(&a); // data_map saved pointer to avoid copy
}
}
int main() {
while(true) {
Data* a = new Data;// here waste memory, since only few data need to be saved
socket.Recv(*a);
Handle(*a);
}
}
in this code, I saved data's pointer, so, the copy cost is saved.
But the problem is I new a lot of objects, which spends a lot of memory.
I have second design like this:
struct Data {
int a;
char b[20];
}; // data type
std::vector<const Data*> data_base;
void Handle(const Data& a) {
if (a.good()) { // only few data will get good
// TODO: copy a's value to a permanent pointer, i don't know how to do that
}
}
int main() {
Data a;
while(true) {
socket.Recv(a); // make a reusable
Handle(*a);
}
}
I think the second solution can save memory, and the performance wont be harmed. (no additional copy), am i right?
And how can I copy a temp variable into a pointer container(see TODO in solution 2)?
Don't do any of that.
Do this instead:
struct Data {
int a;
char b[20];
}; // data type
std::vector<Data> data_base;
void Handle(const Data& a) {
if (a.good()) { // only few data will get good
data_base.push_back(a);
}
}
int main() {
Data a;
while(true) {
socket.Recv(a);
Handle(a);
}
}
Copying your Data struct seems to be pretty trivial, and in any case you've stated that it will only happen rarely anyway. So the right thing to do is to optimize for the common case. Reuse the space for the data for receiving, and make a copy only when you need it.
// TODO: copy a's value to a permant pointer, i dont know how to do that
You could do, it's just:
data_base.push_back(new Data(a))
But your code leaks memory. Use smart pointers:
std::vector<std::unique_ptr<Data>> data_base;
Anyway, I believe the intention is not to copy the data, but copy only pointers and only when needed. Use smart pointers anyway. I believe something along:
struct Data { int tmp; bool good(); };
std::vector<std::unique_ptr<Data>> data_base;
void socket_recv(std::unique_ptr<A>& a);
void handle(std::unique_ptr<Data>& a) {
if (a->good()) { // only few data will get good
data_base.emplace_back(std::move(a)); // we move the pointer around
a = std::make_unique<Data>(); // allocate new memory for next run
}
}
int main() {
std::unique_ptr<Data> a = std::make_unique<Data>();
while(true) {
socket_recv(a); // make a reusable
handle(a);
}
}
or using raw pointers:
std::vector<Data *> data_base;
void socket_recv(Data* a);
void handle(Data*& a) {
if (a->good()) { // only few data will get good
data_base.push_back(a); // we move the pointer around
a = new Data(); // allocate new memory for next run
}
}
int main() {
A *a = new Data();
while(true) {
socket_recv(a); // make a reusable
handle(a);
}
delete a;
}

vector iterators incompatible when deep copying vectors

I am running into this "vector iterators incompatible" assert and I have no idea why. I looked at few answers here but none of them helped. I wonder if anyone can spot the issue. It is basically a vector that I am deep copying, but when I iterate through the copy, it asserts. Code is a bit confusing, but I could not re-pro with a simpler case:
#include <vector>
class MyClass
{
public:
MyClass() {};
~MyClass() {};
virtual MyClass* Clone()
{
MyClass* clone = new MyClass(*this);
return clone;
}
int GetData() const { return m_data; }
private:
int m_data;
};
typedef std::vector<MyClass*> MyClassList;
struct MyStruct
{
MyClassList myClassList;
};
struct MyStruct2
{
MyStruct2() {};
MyStruct *pData2;
};
int _tmain(int argc, _TCHAR* argv[])
{
MyClassList* m_pMyClasssOrig;
m_pMyClasssOrig = new MyClassList();
m_pMyClasssOrig->push_back(new MyClass());
m_pMyClasssOrig->push_back(new MyClass());
m_pMyClasssOrig->push_back(new MyClass());
// Setup worker parameters
MyStruct2* pWorkerParam = new MyStruct2();
MyStruct* pData2 = new MyStruct();
memset(pWorkerParam, 0x00, sizeof(MyStruct2));
memset(pData2, 0x00, sizeof(MyStruct));
pWorkerParam->pData2 = pData2;
// Make deep copy of the myClassList
for (auto pMyClass : *m_pMyClasssOrig)
{
auto decoderCopy = pMyClass->Clone();
pWorkerParam->pData2->myClassList.push_back(decoderCopy);
}
// why do I get "Expression: vector iterators incompatible"
// here?
for (auto i = pWorkerParam->pData2->myClassList.begin(); i != pWorkerParam->pData2->myClassList.end(); i++)
{
MyClass* pMyClass = *i;
(void)pMyClass->GetData();
}
return 0;
}
Don't use memset on a std::vector.
You don't know what std::vector's internals are, so you should not be zeroing them out. If you need to clear the vector, then use the clear method.
Even for your class that just has a pointer in it, don't use memset, make the constructor set the pointer to NULL.
My guess is that the memset is stomping on internal vector state. Try removing that and see if it passes. I ran into this exact problem. See this question. The accepted answer explains.

Adding destructor definition creates running exception

I have a problem with a destructor of struct Heap. Even just adding one, and not using it, creates a runtime exception (memory access). It's second day I try to do it and tomorrow is a deadline.
struct Heap
{
int n;
int* tab;
int* numerWKopcu;
Heap () { n=0; }
Heap (int size) { this->tab = new int[liczbaDomow]; n=0; this->numerWKopcu = new int[2000100];}
int max() { return tab[1]; }
bool empty() { return n==0; }
bool insert(int x)
{
n++;
tab[n]=x;
this->numerWKopcu[x] = n;//ZMIANA
upHeap(n);
return true;
}
bool delMin()
{
if (n<1) return false;
this->numerWKopcu[tab[n]] = 1; //ZMIANA
tab[1]=tab[n]; n--;
downHeap(1);
return true;
}
void upHeap(int x){
int p;
int mem = tab[x];
while (x>1)
{
p=x/2;
if (color[mem]>color[tab[p]]) break;
this->numerWKopcu[tab[p]] = x; //ZMIANA
tab[x]=tab[p];
x=p;
}
this->numerWKopcu[mem] = x;//ZMIANA
tab[x]=mem;
}
void downHeap (int x)
{
int s=2*x;
int mem=tab[x];
while(s<=n)
{
if (s+1<=n && color[tab[s]]>color[tab[s+1]])
s++;
if (color[mem]>color[tab[s]])
{
this->numerWKopcu[tab[s]] = x; //ZMIANA
tab[x]=tab[s];
x=s;
s=2*x;
}
else break;
}
this->numerWKopcu[mem] = x;//ZMIANA
tab[x]=mem;
}
void write ()
{
for (int i=1;i<=n;i++) printf ("%d) %d\n", i, tab[i]);
printf ("\n");
}
void build()
{
int s = n;
for (s=n/2; s>=1; s--) downHeap(s);
}
/ ~Heap() {
delete []this->numerWKopcu;
delete []this-> tab;
};
};
The code is a bit hard to read, but I see two problems:
You aren't initialising the pointers to null in the default constructor, so destroying a default-constructed object gives undefined behaviour;
You don't define or remove the copy constructor and copy assignment operator (as you should always do if you define a destructor, per the Rule of Three), so destroying a copied object gives undefined behaviour.
It's also possible that you're accessing memory outside the array bounds; a memory debugging tool such as valgrind can help you determine whether that's happening.
The simplest solution is to replace your manually-managed arrays with std::vector; then you won't need to worry about writing your own destructors or copy semantics. You can also use at() rather than [] (at least in a debug variant) to give range-checked access.
You are not initializing pointers in default constructor. If you try to destroy default constructed Heap it will try to delete random memory areas in destructor and will definitely break.

why is deleting this object causing problems?

Instantiation:
weapons.push_back(new Pistol());
weapons.push_back(new Rifle());
weapons.push_back(new Shotgun());
destructor, when the first delete happens, the code breaks. This happens when I close the program.
Brain::~Brain()
{
for (unsigned int i = 0; i < weapons.size(); i++)
{
delete weapons[i]; // this is where the code breaks
}
}
I get a warning:
Unhandled exception at 0x0096371f in D3D10DEMO.exe: 0xC0000005: Access violation reading location 0x000002ce.
weapons is this:
weapons(vector<Gun*>())
Edit - I have deleted much of the code from this question but I have also cut down my program so as to reproduce the problem in a much smaller solution here:
http://dl.dropbox.com/u/13519335/D3D10DEMO_0.25.MinRep.zip
You haven't defined virtual destructors for your weapon classes.
http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7
You problem is the definition of
class Brain : public Entity
{
private:
std::vector<Gun*> weapons;
and the ownership of Gun* by Brain object.
Brain::~Brain()
{
for (unsigned int i = 0; i < weapons.size(); i++)
{
delete weapons[i];
}
}
If a Brain is copy constructed the delete will be called multiple times deleting the same Gun from different weapons vector. And a Brain temporary is created when you add your Agents (Agent being a derived class of Brain) like so in main function.
int main()
{
Level* level;
std::vector<Agent> agents;
level = new Level(agents);
for (int i = 0; i < 1; i++)
{
//TODO - health is a pointless parameter here
agents.push_back(Agent(100, *level, agents, level->Pickups(), D3DXCOLOR(1.0F, 0.4f, 0.4f, 1.0f)));
}
delete level;
}
 If you implement a copy constructor for Brain that clones the Gun* vector you should be ok. Alternative you should use shared_ptr<Gun> in your vector so that you don't have to delete them at all.
To summarize your problem boils down to
class Foo{};
class Bar
{
public:
Bar()
{
mFooVec.push_back( new Foo() );
mFooVec.push_back( new Foo() );
}
~Bar()
{
for( unsigned int i = 0;i < mFooVec.size(); ++i )
{
delete mFooVec[i];
}
}
std::vector<Foo*> mFooVec;
};
int main()
{
Bar x;
Bar y = x;
return 0;
}
Here both Bar x and y have the same two Foo* in their mFooVec