C++ Avoiding Deleting Memory Twice - c++

I've run into a problem while working with the built-in pointers in C++. When my program terminates, my classes destructors are all called. I have a data class, a queue class, and another data class which incorporates uses the queue as follows (mind the rough coding on the fly):
class Data {
int x;
}
class Queue {
class Node {
Data* x;
}
Node* head;
}
class C1 {
Queue q;
}
class C1Queue{
class Node {
C1* c;
}
Node* head;
}
I also have another Queue, q2, that does not reside in an object. I load both queues from a file, so I say something along the lines of (assuming cQueue is a C1Queue):
Data *d = new Data(0);
q2->pushBack(d);
C1 c = new C1();
cQueue->pushBack(c->pushBack(d));
As you can see, I have both a queue (q2) holding pointers to each of the data, as well as an object with a queue holding pointers to the same data as q2 is holding.
Now, when my program terminates I want all the data to be deallocated. However, when the objects are being deallocated, either q2 is deallocated first, and when the C1 objects are to be deallocated, then they deallocate their queues, which then deletes the same data as q2 just deleted. Or the other case is that the objects are deallocated first (I'm not sure which ordering occurs), and then q2 is deallocated and it runs into already deleted memory.
So the problem is that the memory space is being deleted twice, which is not good. Once memory has been deleted, it is released to other programs to use, so deleting that memory space again will result in a seg fault.
Maybe I am missing something here, but I can't figure out how to do this without having a special type of pointer (I cannot use a special type of pointer).
The only way I can think of is to block the C1 object from deallocating it's queue but deallocating the rest of itself, but I don't know how to do that. If someone could help me with this then I would much appreciate it.

Since you are (apparently) prevented from using niceties like std::shared_ptr, you can try one of the following three remedies:
Manual refcounting. Enforce that every time a Data is pushed onto a queue that its refcount be incremented, and decrement the refcount as a Queue is cleaned up. When the refcount hits zero, delete this (but make sure you always allocate Datas on the heap!)
Designate an object to "own" the Data elements. Only that object can destroy Data (you may even enforce this with a private destructor and a friend class). You might need more than one of these. (If you refcount this proxy, this becomes a poor man's std::shared_ptr).
Make your Datas copyable, and just do everything with brand new objects. This works if it's a small amount of data that doesn't need to stay in sync (for example, a Point2D class holding two integers).

Related

How do you define a deconstructor in c++?

Just started learning C++ and I'm confused on how to program a deconstructor. So far I understand that a deconstructor is called whenever an object is destroyed, which from my understanding is when the program ends and C++ automatically destroys all objects. Does this just mean that I should just re-intialize all variables back to what they originally were?
So is this what I should have:
/*In the Header file*/
List();
~List();
//Other function prototypes go here
/*In the Implementation file*/
List::List()
{
head = NULL;
tail = NULL;
count = 1;
}
List::~List
{
head = NULL;
tail = NULL;
count = 1;
}
//Other function bodies go here
No. The destructor is for deallocating/cleaning up any resources that the object might be using. For instance file handles need to be closed, UI resources need to be released back to the system, memory that you have newed needs to be deleteed.
In your example count seems like an int, so you don't need to do anything for that as the memory for that is a part of the object being destroyed, but if you have allocated memory for your list you will have to deallocated it in the destructor. Depending on how you have constructed the list you might want to iterate through the list and deallocate each node.
To clear up one misconception, the destructor is called any time an object goes out of scope (a local variable hits the end of the code block in which it was created). If an object was created in global scope (outside of a function) it will be destroyed at program exit. Think of this as a big set of braces around the whole program.
void function(object a)
{
object b;
int x = 0;
while (x < 10)
{
object c;
// La la la Doing stuff.
} // c destroyed here. It will be created and destroyed for each run through the loop
a = b;
} //b destroyed here
// a also destroyed here, so watch out passing things into functions if you want them
// back changed.
or when it is manually destroyed with the delete command
object * d = new object();
// la la la doing stuff
delete d;
Since d was manually created, it must be manually destroyed. Watch out C# and Java people.
What do you need to do in a destructor?
Put everything away. Don't waste your time setting values back to their defaults. They won't be around long enough to appreciate the gesture. But if you opened a file, and still have it open, close it. If you newed other objects, delete them. If you have a mutex locked, unlock it. If you are managing threads, you probably want to notify the threads and wait for them to finish before finishing. But do it with a time-out so you don't hang on a stuck thread.
While we're on the topic, read this: What is The Rule of Three?
Put simply The Rule of Three means if you have a destructor, a copy constructor or an assignment operator (operator=), you almost certainly require all three. A lot of time you'll see people getting odd memory errors because they didn't obey the Rule of Three. Don't be that guy.
When you have The Rule of Three down, go looking for the Rule of Five.
How this applies to the OP:
List::~List
{
head = NULL; //very probably need to delete this pointer
tail = NULL; //and possibly this one
count = 1; // don't need this at all
}
So it should probably look like:
List::~List
{
if (head != NULL)
{
delete head; // This should start a chain reaction deleting all of the linked
// items in the list, ensuring that they have all been freed
}
}
In addition, the OP should have a copy constructor and an assignment operator that make sure that when the List is deleted it doesn't also obliterate the data of any copies of the list.
It is called destructor not deconstructor
A destructor code is generally defines how you may end the life of an instance of a class.
Usually this will include memory deallocation or freeing as well as resource freeing 'closing a file handle', unlocking a synchroniser, it might also include more complicated stuff like interrupting a thread to end it's life if this thread life cycle is inside the class.. it might have more than that like notifying about the destruction of a class to whomever have assigned for a notification .. there is a lot of code that might be required when you end an instance of a class without a destructor the encapsulation of OOP would have suffered
Last note in c++ the new, and delete reserved words are memory allocators that use the constructor/destructor of an instance of an object
I hope it is clear enough

Deleting objects in C++, and the new keyword

A few questions:
I was looking at the following code for a linked list on www.cprogramming.com:
struct node {
int x;
node *next;
};
int main()
{
node *root; // This will be the unchanging first node
root = new node; // Now root points to a node struct
root->next = 0; // The node root points to has its next pointer
// set equal to a null pointer
root->x = 5; // By using the -> operator, you can modify the node
// a pointer (root in this case) points to.
}
Would this code cause a [small] memory leak because he never deletes root at the end?
Also, would this be any different if 'node' was a class instead of a struct?
Finally, for this code:
#include <iostream>
using namespace std;
class A
{
public:
A(){}
void sing()
{ cout << "TEST\n";}
};
int main()
{
A *a = new A();
a->sing();
return 0;
}
Would I have to delete A before exiting main?
In what instances would I use A *a = new A() versus using A a = A() ?
1.1 Yes, although on any modern operating system when the process ends all its memory is reclaimed by the operating system. Memory leaks are a big problem for long lived processes, where memory continues to be leaked and the process continues to ask for more memory for no apparent reason.
1.2 I suppose you meant a class, not an object (an object is an instantiation of a class or of a struct)... still, there would be no difference, class and struct differ only in their default access specifier (public for structs, private for classes).
2.1 Yes (with the same caveat as in 1.1).
2.2 Usually when (a) A is too big to be placed on the stack, (b) when the object lifetime imposed by local variables (=automatic destruction at the end of the scope) is not appropriate, (c) when the number of objects to be create is not known at compile-time.
Examples:
a. A contains in its definition a really big matrix, that would take away a lot of stack space; or, A is not that big, but the current call is recursive, so putting it on the stack would be likely to lead to a stack overflow.
b. A is an object to be returned from this function (and a copy is not acceptable); or, A is to be created in this function and to be deleted in the future by some other function, but not at the end of the current scope.
c. A is a node of a linked list to be populated with data provided by the user; you create and append the nodes in a loop until the user provided data ends.
For the first part:
It might be sloppy (and tools like Valgrind will warn about it), but all memory is freed by the OS when main returns. A memory leak is more of a concern if it persists as the program continues to run.
There is no distinction in C++ between "classes" and "structs". A class simply has its initial access modified as private rather than public.
And for the later part:
Same as 1.
This is a fairly complicated question. Broadly, you'll want to use heap memory allocation (which is what new does) in cases where the object needs to outlive the current scope (e.g. to be returned by the function in which it is constructed) or its size is determined dynamically or can be very large, among other reasons.
Would this code cause a [small] memory leak because he never deletes root at the end?
Yes, however the program is terminated and the memory should be reclaimed by the OS. So any memory leak checks would flag this.
Also, would this be any different if 'node' was an object instead of a struct?
No. Structs and Classes are nearly identical, except that the default protection for a struct is public
Would I have to delete A before exiting main?
Yes. To avoid a memory leak.
In what instances would I use A *a = new A() versus using A a = A() ?
Using operator new will allocate the memory on the heap. It's preferred to allocated on the stack, unless you need your object to live past the life of the stack-frame, in which case you can either return by copy, or allocate it on the heap, where it will remain until it is deleted.
First Part
1) Yes, there is a memory leak.
2) There is no functional difference between a class and a struct.
Second Part
1) Yes, you should delete any object that you allocate on the heap.
2) In any case where you can avoid pointers (and allocating heap memory, for that matter), you should. It takes less time and uses less resources to use the stack.
In this case the lifetime of the object is so short that it makes no sense to use the heap.

The one who `new/malloc` should `delete/free`?

It seems to be a common sense in C/C++ that, the function which new/malloc some memory should delete/free them before the function finishes, right?
But suppose I have this kind of problem that, there is a function reader which will read chunks from a file into buffers, there is another function consumer will consume these buffer latter,
void reader(ifstream &ifs)
{
char *buf = new char[100];
ifs.read(buf, 100);
save_buffer(buf); //save this buf into a global array, say buf_array[10]
}
void consumer()
{
for(int i = 0; i < 10; i++)
consume( buf_array[i] ); //do something with those buffers read by reader
}
My problem is, many memory resources are newed inside reader, but reader cannot delete them, because these buffers haven't been used by consumer. Should consumer be responsible for deleteing those buffers?
No one said the function that allocates memory should free the memory. But generally the same component should handle it. Because your reader and consumer form a pair, it is fine for them to coordinate the memory together.
It seems to be a common sense in C/C++ that, the function which new/malloc some memory should delete/free them before the function finishes, right?
No, this is not necessarily true, you do not have to release memory in the same function, as long as you release it eventually before the program ends.
One common solution available in C++ (but not in C) is to deallocate memory in the destructor. If you pass around objects that contain dynamically allocated memory while dealing correctly with the copy/move constructors and assignment operators, the memory will be released when the destructor is called.
The principle is that "for every new, there should be a delete". That doesn't say anything about both calls having to be within the same function (obviously, that wouldn't be very useful).
There's no problem with your example with the reader allocating and the consumer freeing.
You need not free an allocated buffer in the same function in which you initialized it, as long as you carry around a pointer to the buffer.
In your case, consumer() should be responsible for deleteing the buffers allocated by consumer.
As for your secondary question, consumer doesn't know where the buffer ends; you need to tell it somehow. Instead of just storing pointers to the buffers, you might consider defining a new struct encapsulating both a buffer and its length. This has already been done: consider looking at using std::string.
You are copying the contents of buf to a global array buf_arrray which actually feeds the consumer. So, in the example above reader can free the buf.
And, it is not requrired that the function that new/mallocs should be freeing up the memory. The pointer can be passed around. The function that last uses the memory allocated needs to free it the memory.
You don't have to do new/malloc(allocation) and delete/free(release) in the same function. As long as your algorithm guarantees that every allocation does get released and only gets released once, so that it does not cause memory-leak, it is fine.
In fact, often the allocation and release do exist in separate functions.
Just remember these:
1. Use the same pointer to do the release(you can pass the pointer around of course). If you do some arithmetic on the pointer and then release the allocation using that modified pointer, it would produce an error even the pointer still points in the allocation region.
2. As mentioned above, you should guarantee that the allocation got released, and only once. Additional release causes an error.
Slightly different answer to everyone else:
Yes it is fine for the Reader not to free/delete the memory in the reading function, but I wouldn't have the consumer delete the memory. In a simple case works, but what if you have multiple consumers (e.g. to output in different formats)? If consuming the data has the side effect of freeing it, then you cannot do anything else with the data after the fist consumer does it's thing.
I would have a cleanup() type method in my reader that I explicitly call to cleanup the buffers when required. This way the module that allocates the memory is responsible for freeing it (even though it is in a different method).
e.g.
Data d = Reader.read();
Consumer1.consume(d);
Consumer2.consume(d);
Reader.cleanup(d);
// d is no longer valid.
You could also read about shared arrays http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/shared_array.htm
Using shared arrays, you can allocate them inside a function and pass them by value to other functions. The shared array keeps an internal count of how many times it has been referenced, and deletes the memory automagically when all references have gone out of scope.
eg
void bar( boost::shared_array< int > );
void foo()
{
boost::shared_array< int > x ( new int[ 100 ] );
bar( x );
// because x has been passed to bar(), its reference count is incremented
// and it will not only be deleted when everyone is finished with it!
// do more things with x
} // the memory held by x is deleted
void bar( boost::shared_array< int > y )
{
// Do things with y here
} // the memory held by y is not deleted here because foo() hasn't yet finished
In descending order of preference you'd prefer to:
Use auto storage class, so deletion happens automatically.
Have the same same code allocate and delete objects.
Pass ownership, so one component allocates and another frees.
Have shared ownership via something like shared_ptr.
3 and 4 are nearly tied, but both are quite a ways behind 2, which is quite a ways behind 1.
In this case, what you'd really prefer is for the level of function (or class, etc.) above both the producer and consumer to allocate the buffers, start the producer and consumer, and delete the buffers when both are finished:
class buffer {
std::vector<char> data;
public:
buffer() : data(100) {}
};
process_file(std::string const &name) {
std::vector<buffer> buffers(10);
std::ifstream in(name);
std::pair<std::ifstream *, std::vector<buffer> *> thread_data = {
&in, &buffers
};
prod = start_thread(producer, (void *)&thread_data);
cons = start_thread(consumer);
join(prod);
join(cons);
}
If you can do this, it can help avoid a lot of headaches in managing the memory.

When is a C++ destructor called?

Basic Question: when does a program call a class' destructor method in C++? I have been told that it is called whenever an object goes out of scope or is subjected to a delete
More specific questions:
1) If the object is created via a pointer and that pointer is later deleted or given a new address to point to, does the object that it was pointing to call its destructor (assuming nothing else is pointing to it)?
2) Following up on question 1, what defines when an object goes out of scope (not regarding to when an object leaves a given {block}). So, in other words, when is a destructor called on an object in a linked list?
3) Would you ever want to call a destructor manually?
1) If the object is created via a pointer and that pointer is later deleted or given a new address to point to, does the object that it was pointing to call its destructor (assuming nothing else is pointing to it)?
It depends on the type of pointers. For example, smart pointers often delete their objects when they are deleted. Ordinary pointers do not. The same is true when a pointer is made to point to a different object. Some smart pointers will destroy the old object, or will destroy it if it has no more references. Ordinary pointers have no such smarts. They just hold an address and allow you to perform operations on the objects they point to by specifically doing so.
2) Following up on question 1, what defines when an object goes out of scope (not regarding to when an object leaves a given {block}). So, in other words, when is a destructor called on an object in a linked list?
That's up to the implementation of the linked list. Typical collections destroy all their contained objects when they are destroyed.
So, a linked list of pointers would typically destroy the pointers but not the objects they point to. (Which may be correct. They may be references by other pointers.) A linked list specifically designed to contain pointers, however, might delete the objects on its own destruction.
A linked list of smart pointers could automatically delete the objects when the pointers are deleted, or do so if they had no more references. It's all up to you to pick the pieces that do what you want.
3) Would you ever want to call a destructor manually?
Sure. One example would be if you want to replace an object with another object of the same type but don't want to free memory just to allocate it again. You can destroy the old object in place and construct a new one in place. (However, generally this is a bad idea.)
// pointer is destroyed because it goes out of scope,
// but not the object it pointed to. memory leak
if (1) {
Foo *myfoo = new Foo("foo");
}
// pointer is destroyed because it goes out of scope,
// object it points to is deleted. no memory leak
if(1) {
Foo *myfoo = new Foo("foo");
delete myfoo;
}
// no memory leak, object goes out of scope
if(1) {
Foo myfoo("foo");
}
Others have already addressed the other issues, so I'll just look at one point: do you ever want to manually delete an object.
The answer is yes. #DavidSchwartz gave one example, but it's a fairly unusual one. I'll give an example that's under the hood of what a lot of C++ programmers use all the time: std::vector (and std::deque, though it's not used quite as much).
As most people know, std::vector will allocate a larger block of memory when/if you add more items than its current allocation can hold. When it does this, however, it has a block of memory that's capable of holding more objects than are currently in the vector.
To manage that, what vector does under the covers is allocate raw memory via the Allocator object (which, unless you specify otherwise, means it uses ::operator new). Then, when you use (for example) push_back to add an item to the vector, internally the vector uses a placement new to create an item in the (previously) unused part of its memory space.
Now, what happens when/if you erase an item from the vector? It can't just use delete -- that would release its entire block of memory; it needs to destroy one object in that memory without destroying any others, or releasing any of the block of memory it controls (for example, if you erase 5 items from a vector, then immediately push_back 5 more items, it's guaranteed that the vector will not reallocate memory when you do so.
To do that, the vector directly destroys the objects in the memory by explicitly calling the destructor, not by using delete.
If, perchance, somebody else were to write a container using contiguous storage roughly like a vector does (or some variant of that, like std::deque really does), you'd almost certainly want to use the same technique.
Just for example, let's consider how you might write code for a circular ring-buffer.
#ifndef CBUFFER_H_INC
#define CBUFFER_H_INC
template <class T>
class circular_buffer {
T *data;
unsigned read_pos;
unsigned write_pos;
unsigned in_use;
const unsigned capacity;
public:
circular_buffer(unsigned size) :
data((T *)operator new(size * sizeof(T))),
read_pos(0),
write_pos(0),
in_use(0),
capacity(size)
{}
void push(T const &t) {
// ensure there's room in buffer:
if (in_use == capacity)
pop();
// construct copy of object in-place into buffer
new(&data[write_pos++]) T(t);
// keep pointer in bounds.
write_pos %= capacity;
++in_use;
}
// return oldest object in queue:
T front() {
return data[read_pos];
}
// remove oldest object from queue:
void pop() {
// destroy the object:
data[read_pos++].~T();
// keep pointer in bounds.
read_pos %= capacity;
--in_use;
}
~circular_buffer() {
// first destroy any content
while (in_use != 0)
pop();
// then release the buffer.
operator delete(data);
}
};
#endif
Unlike the standard containers, this uses operator new and operator delete directly. For real use, you probably do want to use an allocator class, but for the moment it would do more to distract than contribute (IMO, anyway).
When you create an object with new, you are responsible for calling delete. When you create an object with make_shared, the resulting shared_ptr is responsible for keeping count and calling delete when the use count goes to zero.
Going out of scope does mean leaving a block. This is when the destructor is called, assuming that the object was not allocated with new (i.e. it is a stack object).
About the only time when you need to call a destructor explicitly is when you allocate the object with a placement new.
1) Objects are not created 'via pointers'. There is a pointer that is assigned to any object you 'new'. Assuming this is what you mean, if you call 'delete' on the pointer, it will actually delete (and call the destructor on) the object the pointer dereferences. If you assign the pointer to another object there will be a memory leak; nothing in C++ will collect your garbage for you.
2) These are two separate questions. A variable goes out of scope when the stack frame it's declared in is popped off the stack. Usually this is when you leave a block. Objects in a heap never go out of scope, though their pointers on the stack may. Nothing in particular guarantees that a destructor of an object in a linked list will be called.
3) Not really. There may be Deep Magic that would suggest otherwise, but typically you want to match up your 'new' keywords with your 'delete' keywords, and put everything in your destructor necessary to make sure it properly cleans itself up. If you don't do this, be sure to comment the destructor with specific instructions to anyone using the class on how they should clean up that object's resources manually.
Pointers -- Regular pointers don't support RAII. Without an explicit delete, there will be garbage. Fortunately C++ has auto pointers that handle this for you!
Scope -- Think of when a variable becomes invisible to your program. Usually this is at the end of {block}, as you point out.
Manual destruction -- Never attempt this. Just let scope and RAII do the magic for you.
To give a detailed answer to question 3: yes, there are (rare) occasions when you might call the destructor explicitly, in particular as the counterpart to a placement new, as dasblinkenlight observes.
To give a concrete example of this:
#include <iostream>
#include <new>
struct Foo
{
Foo(int i_) : i(i_) {}
int i;
};
int main()
{
// Allocate a chunk of memory large enough to hold 5 Foo objects.
int n = 5;
char *chunk = static_cast<char*>(::operator new(sizeof(Foo) * n));
// Use placement new to construct Foo instances at the right places in the chunk.
for(int i=0; i<n; ++i)
{
new (chunk + i*sizeof(Foo)) Foo(i);
}
// Output the contents of each Foo instance and use an explicit destructor call to destroy it.
for(int i=0; i<n; ++i)
{
Foo *foo = reinterpret_cast<Foo*>(chunk + i*sizeof(Foo));
std::cout << foo->i << '\n';
foo->~Foo();
}
// Deallocate the original chunk of memory.
::operator delete(chunk);
return 0;
}
The purpose of this kind of thing is to decouple memory allocation from object construction.
Remember that Constructor of an object is called immediately after the memory is allocated for that object and whereas the destructor is called just before deallocating the memory of that object.
Whenever you use "new", that is, attach an address to a pointer, or to say, you claim space on the heap, you need to "delete" it.
1.yes, when you delete something, the destructor is called.
2.When the destructor of the linked list is called, it's objects' destructor is called. But if they are pointers, you need to delete them manually.
3.when the space is claimed by "new".
Yes, a destructor (a.k.a. dtor) is called when an object goes out of scope if it is on the stack or when you call delete on a pointer to an object.
If the pointer is deleted via delete then the dtor will be called. If you reassign the pointer without calling delete first, you will get a memory leak because the object still exists in memory somewhere. In the latter instance, the dtor is not called.
A good linked list implementation will call the dtor of all objects in the list when the list is being destroyed (because you either called some method to destory it or it went out of scope itself). This is implementation dependent.
I doubt it, but I wouldn't be surprised if there is some odd circumstance out there.
If the object is created not via a pointer(for example,A a1 = A();),the destructor is called when the object is destructed, always when the function where the object lies is finished.for example:
void func()
{
...
A a1 = A();
...
}//finish
the destructor is called when code is execused to line "finish".
If the object is created via a pointer(for example,A * a2 = new A();),the destructor is called when the pointer is deleted(delete a2;).If the point is not deleted by user explictly or given a new address before deleting it, the memory leak is occured. That is a bug.
In a linked list, if we use std::list<>, we needn't care about the desctructor or memory leak because std::list<> has finished all of these for us. In a linked list written by ourselves, we should write the desctructor and delete the pointer explictly.Otherwise, it will cause memory leak.
We rarely call a destructor manually. It is a function providing for the system.
Sorry for my poor English!

is this safe? (qt QQueue.dequeue() c++ inline pointer dereference)

Object object = *(queue.dequeue());
queue is a QQueue<Object*>. i'm concerned that the dequeued pointer is deleted before i dereference it. of course i can access object's data but that doesn't mean anything. doing it all in one line like this is convenient (i don't want a pointer because i want object to be deleted automatically when it goes out of scope) but if it's not safe then i can't do it. please advise. thanks.
It isn't immediately unsafe per se, but chances are you'll be using it wrong.
All your code does is make a copy of the element pointed to by the last element of queue. By dequeuing the element, you lose the pointer to it, and you now have no way of freeing that original object in case it was dynamically constructed.
Correct example (no dynamic objects, no leak):
QQueue<Foo*> q;
{
Foo a;
q.enqueue(&a);
Foo b = *q.dequeue();
}
Broken example (dynamic object leaked):
QQueue<Foo*> q;
q.enqueue(new Foo); // eeew, naked "new" in C++...
Foo c = *q.dequeue();
// now the newed element is leaked
You're right that c is safely destroyed at the end of its scope, but you're leaking the orginal, new'ed object, to which you have no pointer or reference now.