Memory Management Confusion C++ - c++

I'm having trouble understanding some basic memory management principles in C++. This code is part of a loop that is part of a function that reads in a maze file into a 2D vector.
According to Valgrind, the following code is causing memory leaks...
Note that t is a MazeNode object and verts is a vector within the t class that holds pointers to node objects (not to be confused with MazeNode objects):
node* top = new node(TOP, rowCount, i, t.type);
node* bot = new node(BOTTOM, rowCount, i, t.type);
node* left = new node(LEFT, rowCount, i, t.type);
node* right = new node(RIGHT, rowCount, i, t.type);
t.verts.push_back(top);
t.verts.push_back(bot);
t.verts.push_back(left);
t.verts.push_back(right);
temp.push_back(t);
top = NULL;
bot = NULL;
left = NULL;
right = NULL;
delete top;
delete bot;
delete left;
delete right;
Initially I did not set each of the pointers to NULL before deleting them, but would get allocation errors. So I just set them to NULL and my code works. I guess I'm just really confused why this would cause memory leaks and why I would need to set the pointers to NULL. There is probably a way easier non-pointer way to do this, but maybe this problem will help me understand memory management better.
Thanks everyone.
EDIT: Here's the MazeNode class (which is what 't' is) (also excuse my lazyness in writing this class, making everythign public like a struct)
class MazeNode
{
public:
void setType(char c);
char getChar();
NodeType type;
vector<Direction> visitedFrom;
vector<node*> verts;
};
And the node class:
class node
{
public:
node();
node(Direction d, int r, int c, NodeType t);
~node(); //empty definition
node(const node* n);
node& operator=(const node& n);
void addAdj(node* a, int w);
void printAdj() const;
string direction() const;
void print() const;
bool operator<(const node& n) const;
int distance; //from start
bool visited;
node* prev;
vector<Edge> adj;
Direction dir;
int row, col;
NodeType type;
};
EDIT2: Thanks everyone. I understand the problem now. I changed my vectors of pointer objects so that I wasn't using pointers anymore.

Prior to adding the null assignment, your code had a problem different (worse) than a memory leak: storing and probably also using a stray pointer, that is, a pointer pointing into de-allocated memory.
Making it a memory leak by adding the null assignment makes it better, but not much.
The real solution is not to keep any pointers anywhere after you have called delete on them.
That is, do not push_back or do not delete here.

You are placing the pointers into a container, then deleting the pointers. When your code later tries to use those pointers they are invalid and cause a crash.
By setting the pointers to NULL before you delete them, you end up not deleting them at all - deleting a NULL pointer doesn't do anything. But now there's nothing to delete the objects later, and you get a memory leak.
You need to find some spot in the code where you're not using the pointers anymore, and delete them there.
Edit: Of course I should have mentioned that a smart pointer such as std::shared_ptr eliminates this hassle altogether, because it deletes the object automatically.

You are setting the values to NULL before deleting them, so you are trying to delete NULL and nothing is being deleted. Try moving the delete calls above the NULL calls.

This confusion is exactly why I create a macro for these kind of things:
#define delobj(obj) (delete obj, obj = NULL)
And you would use it like this:
delobj(top);
delobj(bot);
delobj(left);
delobj(right);

The error is using the vector of pointers. According to you, verts is this:
vector<node*> verts;
But what it should be is this:
vector<node> verts;
In the first case, when you push_back() the pointer, that's OK, but when you pop_back or otherwise re-size the vector, the pointer is the "contents" of the vector, and is de-allocated, but not what the pointer points to, which is the node. Hence the node leaks. But in the second case, the node is "part" of the vector, and is allocated/deallocated as part of re-sizing the vector.
Your pattern here probably indicates a Java/C# background, as "new-ing" into a container is very very common in those languages, but to do that in C++, you need a container of smart pointers (like vector<shared_ptr<node>> or something), which is probably beyond the scope of the question. But in those languages, every reference to a reference type is a "smart pointer" (more or less) and so this is done automatically. C++ isn't like that.
You either need to change your code to use a vector<node> (and change how you're pushing back on to it) or you need to explicitly de-allocate your nodes when the vector shrinks.

Change to:
delete top;
delete bot;
delete left;
delete right;
top = NULL;
bot = NULL;
left = NULL;
right = NULL;
And it should work.

Related

Deleting linked objects

I have two classes: "node" and "poly". The node objects are linked together to form a linked list. The poly object holds a pointer to the first node. I am trying to deallocate the memory for the entire "poly". I want to delete the poly - then within the poly destructor call a function (something like "freePoly") that will help me iterate through the entire linked list of node objects - deleting all nodes.
Here is the class definition:
class Node
{
private:
double coeff;
int exponent;
Node *next;
public:
Node(double c, int e, Node *nodeobjectPtr)
{
coeff = c;
exponent = e;
next = nodeobjectPtr;
}
~Node()
{
printf("Node Destroyed");
//???
}
class poly
{
private:
Node *start;
public:
poly(Node *head) /*constructor function*/
{
start = head;
}
~poly() /*destructor*/
{
//???
}
void freePoly();
};
void poly::freePoly()
{
//???
}
I've tried a lot of things, but essentially I get stuck where I'm only deleting the first node object. Then I've lost the pointer to the other nodes... and leak memory because I can't access them anymore for deletion.
You can avoid a lot of problems and work by using a std::vector instead of a Do-It-Yourself linked list. Unless this is for learning.
That said, do
~poly() /*destructor*/
{
while( start != 0 )
{
node* p_doomed = start;
start = start->next;
delete p_doomed;
}
}
There are also many other ways to do this, but the above is a pattern that can help you figure out how to do similar things.
If you want to keep your code as is, then your freePoly should look like this:
while(start)
{
Node *ptr = start;
start = start->getNext();
delete ptr;
}
Notice what this code does: first it makes a copy of the pointer to the current head - i.e. the first Node, then it makes head point to the next object and only then calls delete for the old head pointer.
Of course, this design isn't ideal: you are programming using a C++ compiler and you have some classes and some member functions but you aren't really using C++ effectively:
Not only does language provides you with wonderful tools such as std::list or std::vector so that you don't have to reinvent the wheel and things like std::unique_ptr so that pointers know when it's safe to delete themselves.
It also provides you with powerful abstract concepts to model the bahavior of objects.
I suggest that you take a step back and rethink your code. Key questions to ask are: how can I write less code here? What facilities of C++ can I leverage here? What are these objects I have and what does each object do?
I understand that this may be a homework exercise and you have to implement things a certain way, but don't let that stop you from learning.
You could try this:
private:
void auxDestroy(Node* p);
void Node::auxDestroy(Node* p){
if (p!=0) {
if (p->next != 0) {
auxDestroy(p->next);
}
else {
delete p;
}
}
}
Then in the destroy method you could call this auxDestroy(this->next);
~Node(){
auxDestroy(this->next);
}
And in poly destructor:
~poly(){
delete this->start;
}

Delete a Linked List before closing a C++ program?

I have a doubt which is as follows...
Linked List deals with pointers and dynamic allocation. So they have provided a keyword new which allocates a chunk(that's how it's spelled I suppose) of memory in the heap store and returns a pointer pointing to it. And they have also provided the delete keyword which frees the memory to which the pointer returned by the new is pointing.
So suppose I've created a Linked List of say 10 nodes then should I have to create a function to scan through each node and delete each node? Because in my textbook they have written that if you don't delete a dynamically allocated object then it causes memory leak...
So in short do I have to scan through each node deleting each node before closing a C++ console application??
Aditional Details
Operating System Windows 7
Compiler Turbo C++
It is a good practice that for each memory allocated, there is a class or function responsible for freeing it if it won't be used any more.
Still, all the memory used by program will be freed by operating system when the program is closed. But I think that your teacher (homework, isn't it?) or boss would rather you freed the memory.
The bottom line is: delete everything you created with new.
So in short do I have to scan through each node deleting each node
before closing a C++ console application??
Sure you can delete it before closing your problem, if you did not delete it, then operating system will anyway clear memory consumed by your application / program.
Once, if you know, your heap memory is no more useful better to delete it (instead of waiting for closing program)
{
Allocation with new...
call function(using allocated memory)
....
....
call function2(using allocated memory)
not using allocated memory here after..
**Delete Your heap memory..**
call AnotherFunction()
....
...
Alternatively, you can release / delete memory here also. (Good practice than not deleting :) )
end of main / application.
}
No, you don't actually have to do so.
Nearly all code should, however, be written in a way that the data gets deleted when the object that owns it goes out of scope, so this will happen (almost) unavoidably.
In other words, you should not normally have something like:
// WARNING: bad code. Avoid this, or anything similar.
struct node {
int data;
struct node *next;
};
node *head = NULL;
int main() {
node *t = new node;
t->data = 1;
t->next = head;
head = t;
t = new node;
t->data = 2;
t->next = head;
head = t;
// here, do we bother to delete the two nodes or not?
};
Instead, what you normally want to do is create a class that encapsulates all the work, and in its destructor it frees all the memory it owns:
class linked_list {
struct node {
int data;
node *next;
node(int data, node *next = NULL) : data(data), next(next) {}
} *root;
public:
void add(int data) {
root = new node(data, root);
}
~linked_list() {
node *prev = root;
for (node *temp = prev->next; temp!=NULL; temp=temp->next) {
delete prev;
prev = temp;
}
delete prev;
}
};
With a class like this, there's really no decision to make:
int main() {
linked_list x;
x.add(1);
x.add(2);
}
When execution reaches the end of the block in which x was defined, x goes out of scope and gets destroyed. In the process, its destructor is invoked, and that deletes the nodes in the linked list (modulo any bugs in my code, of course). There's no need to think or care about whether it makes sense to delete the nodes in this case, because it simply happens automatically every time.
Note that I'm not saying this code is (even close to) 100% ideal either. With a compiler modern enough to support it you'd almost certainly want it to be a template to allow storing an arbitrary type, and use a unique_ptr and make_unique instead of a raw pointer and raw new. Unfortunately, I have little choice but to leave these out, since I'm sure Turbo C++ doesn't support unique_ptr, and doubt it supports templates either. For real use, this should also include a copy constructor and assignment operator as well, so assigning and copying linked lists would work correctly (as it stands now, either will typically lead to problems because it'll end up attempting to destroy the nodes in the linked list twice).
Final note: of course, you usually shouldn't write your own linked list code anyway. But when/if you do have a reason to writer a container (or something similar) it should clean up its own mess, so to speak. One of the real strengths of C++ is deterministic destruction; use it.

Unable to populate vector inside struct

I'm new to C++ so bear with me.
I made a struct that looks like this:
struct node{
double startPoint;
double endPoint;
vector<node*> children;
void addChild(node *aNode){
children.push_back(aNode);
}
void addPoints(double start, double end){
startPoint = start;
endPoint = end;
}
};
Down the line in my program, I have the following:
vector<node*> data;
....
node *temp = (node*)malloc(sizeof(node));
temp->addPoints(lexical_cast<double>(numbers[0]), lexical_cast<double>(numbers[1]));
data[index]->addChild(temp);
where "Index" is a index of the vector data. the lexical_cast stuff is taking those numbers from string to doubles.
Everything works until the addChild(temp) line.
The terminal spit this out:
First-chance exception at 0x585b31ea (msvcr90d.dll) in Tree.exe: 0xC0000005: Access violation reading location 0xcdcdcdc1.
Unhandled exception at 0x585b31ea (msvcr90d.dll) in Tree.exe: 0xC0000005: Access violation reading location 0xcdcdcdc1.
But I have no idea how to deal with that.
malloc allocates some space, but doesn't put anything in it. It works fine for plain-old-data structures (or trivially initializable classes), and in C that's all you have.
In C++ you have classes, like std::vector amongst others, which need to be properly constructed in order to establish some invariants. This is done with a straight declaration for objects with automatic storage duration, but for dynamically-allocated objects you need to use new instead of malloc.
For example,
std::vector<int> global; // (1)
void foo() {
std::vector<int> local; // (2)
std::vector<int> *bad = malloc(sizeof(*bad)); // (3)
std::vector<int> *good = new std::vector<int>; // (4)
std::unique_ptr<std::vector<int>> better(new std::vector<int>); (5)
}
is fine - this global is initialized (by which I mean the constructor is called) automatically
is fine - this local variable is also constructed automatically, and destroyed properly as soon as foo exits
you can't use bad for anything, because any method you call will assume the constructor ran already, and it didn't
ok, you can't use bad for anything without explicitly constructing it using placement new. You shouldn't do this though, it's only appropriate where you're doing clever or tricky stuff with custom allocation.
this is ok (but note you have to delete it manually - foo has a memory leak)
this is better - you don't need to clean up manually
Now, note that your node class also has a constructor. In this case, it's automatically-generated, and does nothing but call the vector constructor. Still, you need it to be called, which means using new for dynamically allocating a node.
So, your program should probably look more like:
std::vector<std::unique_ptr<node>> data;
...
std::unique_pre<node> temp(new node);
temp->addPoints(...);
data[index]->addChild(temp);
Note I'm assuming data[index] is valid (I see from addChild you know how to populate a vector already), and that the single-owner model implemented by unique_ptr is appropriate.
As far as the code I see, you never add any nodes into the data array
data.push_back(something);
So accessing data[index] would be out of the allocated memory of the array. It won't complain until you try to set memory in that block (via addChild trying to push an element into the children array).
I would recommend that you store a node instead of a node* in your vector so you don't have to manage the memory on your own.
this is C++ so you don't have to malloc the space for a node you can use new like so:
Node * n = new Node();
New is much better because it calls the constructor and allocates space, whereas malloc just does the latter.
You haven't shown much of your code, but I would restructure the node class like this.
struct node{
double startPoint;
double endPoint;
vector<node> children;
node(){} //add default constrcutor
void addChild(node aNode){
children.push_back(aNode);
}
node & operator=(const node & n) {
startPoint = n.startPoint;
endPoint = n.endPoint;
return *this;
}
node(double start, double end): startPoint(start),endPoint(end){
} //in c++ you have constructors which this should have been in the first place
//constructors are used for initializing objects
};
this is better is that now you can't pass add child nullptr avoiding a lot of problems in your code. You also have a constructor now. Now you can add a node like this.
node temp(start,end); data[index]=temp;
You have a constructor now which addPoints should have been in the first place
I also made an assignment operator
Using the style of coding where you allocate memory on the stack and don't use new is called RAII and is a vital technique for learning c++ and producing exception safe code, this is the main reason I advocate not storing node*'s

Query related to memory management in C++

Hi i have a general query regarding memory management in C++.
With the help of this program only i understood that new is used to allocate memory on heap and temporary variables are allocated memory on stack.And that if we are allocating memory on the heap we have to free it also manually else there will be memory leak.
But in the program i am updating an object of BST struct in a function named Insert by creating a new variable temp of type BST on heap.But then i am not sure how to free that memory.If i use the free command at the end of the function i.e free(temp) then the value stored at that memory will be lost and i will get an error if i try to access it again,and i certainly cannot use free(temp) in main as it is not a local variable to main.
Can some one tell me what should be done.
Btw i must mention that without using free(temp) also my program is working correctly but then i guess memory leak is happening which is bad.
Also i am a little confused as why my program is running without errors if i comment the destructor ~BST() but giving linker errors when i uncomment it.
#include<iostream>
#include<string>
#include<conio.h>
#include<array>
#include<stack>
#include<sstream>
#include<algorithm>
#include<vector>
#include<ctype.h>//isdigit
#include<deque>
#include<queue>
#include<map>
using namespace::std;
struct BST
{
int data;
BST *left;
BST *right;
BST(int d,struct BST* l,BST *r):data(d) , left(l) ,right(r)
{
}
BST()
{
}
//~BST();
};
void levelOrder(struct BST *root)
{
struct BST *temp=NULL;
int count =0;
deque<struct BST*> dq;
if(!root)
{
return;
}
dq.push_back(root);
count=dq.size();
while(!dq.empty())
{
temp=dq.front();
cout<<temp->data<<" ";
if(temp->left)
{
dq.push_back(temp->left);
}
if(temp->right)
{
dq.push_back(temp->right);
}
dq.pop_front();
if(--count==0)
{
cout<<endl;
count=dq.size();
}
}
}
void Insert(struct BST*root,int data)
{
//struct BST temp(data,NULL,NULL);
BST *temp = new BST(data,NULL,NULL);
temp->data =data;
temp->left= NULL;
temp->right=NULL;
if(!root)
{
return;
}
while(root)
{
if((root)->data >data)
{
(root)=(root)->left;
if(!(root)->left)
{
(root)->left=temp;
break;
}
}
else
{
(root)=(root)->right;
if(!(root)->right)
{
(root)->right=temp;
break;
}
}
}
}
int main()
{
deque<struct BST> dq1,dq2;
BST e(4,NULL,NULL);
BST f(3,NULL,NULL);
BST d(1,&f,NULL);
BST b(2,&d,&e);
BST c(8,NULL,NULL);
BST a(6,&b,&c);
levelOrder(&a);
Insert(&a,5);
cout<<a.left->right->right->data;
cout<<endl;
levelOrder(&a);
_getch();
return 0;
}
First, in C++ you should generally use new and delete (they call ctors/dtors, etc.) For arrays, use delete[]. new/delete is not compatible with malloc/free.
I guess BST is a binary search tree. So you have a tree of dynamically allocated memory.
You must free this whole tree, and which means you should do it in order too, lest you get dangling pointers.
One could significantly reduce the complexity by making sure that a BST-node always free's its children. Then when you delete the root node, it will recursively delete all the other nodes.
In my opinion, the easiest way to do this is to use a smart pointer, like shared_ptr<T>, unique_ptr<T> or auto_ptr (the last one has caveats, but I'm not gonna address them here.)
The structure would then look like:
struct BST
{
/* ctor, dtor omitted for brevity. */
std::unique_ptr<BST> left;
std::unique_ptr<BST> right;
}
Your BST-node goes out of scope, that is, you delete it, or it is allocated on the stack and the code exits the block. The destructors for left and right is called and the unique_ptr implementation makes sure to call delete on the pointer it stores.
The BST *temp created in your Insert method is the new node/subtree that you insert, you don't want to delete it until either the entire tree is destroyed or the node is deleted in some kind of Delete function that you haven't written yet.
Regarding your last point:
Running this particular program without a destructor will leak memory, but not access any invalid memory segments, that's why it runs without any errors.
When you uncomment the destructor declaration in your code, you get linker errors because you haven't defined the destructor, you have just told the compiler/linker that there should be a destructor, but there is none. Even if you just want an empty one, it would have to be ~BST() {}.
Both constructors should assign default values to the left right members, at least NULL;
They should not be assigned values outside the class. Add default parameters to the constructor. To avoid leakage you should not create the object until you need it. Alternatively have a flag, initially false, that you set to true if you've used it. And then delete on return if the flag is still false.
First of all, you should use new and delete for memory management in C++, not malloc() and free().
With that said, note that you assign another pointer, either left or right to point to the memory which is originally allocated to the variable temp. Your tree will give you access to the allocated memory, albeit via other variables than the original temp variable. This means that you can delete the memory using these variables in your BST class. Typically this is done inside the destructor.
Note that you are managing memory here, not variables. Let's look at the difference with a simple example:
int main() {
int* intPtr = new int;
int* temp = intPtr;
delete temp;
temp = NULL;
}
As you can see, this code allocates a single block of memory to store an int. This memory has two pointers to it. You can delete the memory with either pointer, just as long as you don't delete with both. This is definitely a balancing act when you learn about memory management. You must be sure that all memory is deallocated while never attempting to deallocate the same block of memory twice.

What's the best way to resolve this scope problem?

I'm writing a program in python that uses genetic techniques to optimize expressions.
Constructing and evaluating the expression tree is the time consumer as it can happen
billions of times per run. So I thought I'd learn enough c++ to write it and then incorporate it
in python using cython or ctypes.
I've done some searching on stackoverflow and learned a lot.
This code compiles, but leaves the pointers dangling.
I tried this_node = new Node(... . It didn't seem to work. And I'm not at all sure how I'd
delete all the references as there would be hundreds.
I'd like to use variables that stay in scope, but maybe that's not the c++ way.
What is the c++ way?
class Node
{
public:
char *cargo;
int depth;
Node *left;
Node *right;
}
Node make_tree(int depth)
{
depth--;
if(depth <= 0)
{
Node tthis_node("value",depth,NULL,NULL);
return tthis_node;
}
else
{
Node this_node("operator" depth, &make_tree(depth), &make_tree(depth));
return this_node;
}
};
The Node object returned by make_tree() is just a temporary object, it will automatically be destroyed again at the end of the expression in which the function is called. When you create a pointer to such a temporary object, like in &make_tree(depth), this pointer will not point to anything useful anymore once the temporary object got destroyed.
You should use real dynamic memory allocation with new and delete to build the tree, so that you don't end up with pointers to not longer existing objects. Probably this construction of the tree should be done in a constructor of the Node class, the destructor should then take care of the deletes needed to release the used memory. For example:
class Node {
public:
const char *cargo;
int depth;
Node *left;
Node *right;
Node(int a_depth);
~Node();
};
// constructor
Node::Node(int a_depth) {
depth = a_depth;
a_depth--;
if(a_depth <= 0)
{
cargo = "value";
left = NULL;
right = NULL;
}
else
{
cargo = "operator";
left = new Node(a_depth);
right = new Node(a_depth);
}
}
// destructor
Node::~Node() {
delete left;
delete right;
}
The C++ way would be to use smart pointers.
Here you're returning copies of local objects, making temporary objects. Once the make_node call is finished the object don't exist anymore making your pointers dangling.
So don't do that.
Use smart pointers instead to allow the nodes to be freed once unreferenced.