problems with [code]delete[/code] in destructor

Hi, I cant figure out how to solve this problem. I have to create some node class and it is supposed to have a pointer to another node as data member.

1
2
3
4
5
6
7
struct Tnode {

	Tnode* random_node;

	Tnode(Tnode* p) : random_node{p} {}
	~Tnode() { delete random_node;}
};


I suppose I have to create destructor for it because someone can supply random_node allocated on free store.

But problem occurs if someone is doing the opposite. Instead of allocating new Tnode* on free store to create new Tnode he creates it giving reference of already existing Tnode.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main() {

	Tnode N{ nullptr };

	{	//this is working fine
		Tnode node1{ new Tnode{ nullptr} };
	}

	{	//this is of course not working
		Tnode node2{ &N };
		//cant delete this
	}

	return 0;
}


The question is how can I make both variants work?
Last edited on
Then I think it is not your responsibility to manage the memory.
As alternative you may make a copy (clone) that you know would be on the heap.


¿Why is the client working with nodes? ¿Shouldn't that be internal to your graph/tree/list?
So there is no way around this - u either choose to use class one way or another and implement it that way?

U are probably right but I just saw this problem and wanted to ask if there is some smart way I could use this class both ways

Ok tnx a lot for answer man. Ill still leave this unanswered in case someone would like to add his thoughts :)
Last edited on
The general convention is that it is the responsibility of whoever allocated memory on the heap with new to deallocate it with delete when the time is right, unless a library or function documents very clearly that the user is expected to undertake one or both of these tasks. The most common way I see this is with old C libraries, that wrap this in initialise and release functions.

If I ever get such a library function, the first thing I do is wrap it in something else that handles the memory for me so I never have to think about it again.

If your class doesn't call new, it shouldn't call delete.
Last edited on
Ok tnx man, I think this question now might be checked as answered :)
What you can do is you can pass in a function pointer or a functor or a lambda expression and use that to tidy up memory.
so for example your constructor would look something like this:

To delete pointer
 
Tnode x{ new Tnode{ nullptr}, [](auto arg){delete arg;} };

To NOT delete pointer
 
Tnode x{ &N, [](auto arg){} };

The lambda can be stored as a function pointer and then referenced back at time of deletion.

Handling a functor is a little trickier though.

An alternative (and simpler method), is simply having a boolean variable to determine whether or not to delete your pointer, modifying the constructor to model something like this:

To delete pointer
 
Tnode x{ new Tnode{ nullptr}, true };

To NOT delete pointer
 
Tnode x{ &N, false };
Last edited on
Topic archived. No new replies allowed.