say I add several posnodes to a match, and if I use delete on the match struct, the posnodes would have no pointers to them. Is the only way to be absolutely sure to avoid a memory leak to iterate through the list and delete all the nodes on the way through before using delete on the match struct?
and I think I see the reason that code crashes, deleting c if c->next == a attempts to deletes the entire list, because if I remove the comment it becomes a circular list; I dont intend to be using circular lists, and whenever I delete these objects it will be deleted from the head to the tail. Individual nodes are only added once I'm sure they belong there, so they wouldn't be deleted by themselves. Besides, if they were, i'd have fixed the references involved effectively removing them from the linked list and rendering them into isolated nodes beforehand.
If we take a look at the destructor you wrote, writing it this way keeps it from looping like crazy, but it still drags the destructor into parts of memory that it doesn't belong if you try to delete any of the nodes and then delete any other node following that without setting the reference to null first. With this destructor you can destroy the linked list in circular form by using delete at any point in the loop.
1 2 3 4 5 6 7 8 9 10 11 12 13
|
~Node()
{
Node* temp;
cout<< "I'm->" << Id << " : I'm inside the destructor\n";
/**/
if(next !=NULL)
{
temp=next;
next=NULL;
delete temp;
}
//*/
}
|
However my code isn't like this, it has the following structs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
struct Posnode
{
unsigned short int file;
short int pos;
struct Posnode *next;
Posnode(char f,short int p)
{
file=f;
pos=p;
next=NULL;
}
void insert_after(struct Posnode *p)
{
struct Posnode *temp;
temp=next;
next=p;
p->next=temp;
}
#ifdef DEBUG_DESTRUCTORS
~Posnode(void)
{
cout<<"posnode deleted"<<endl;
}
#endif
};
typedef struct Posnode posnode;
struct Match
{
struct Posnode *head;
struct Posnode *tail;
struct Match *next;
Match(void)
{
head=NULL;
tail=NULL;
next=NULL;
}
void addpos(struct Posnode *p)
{
if(head==NULL)
{
head=p;
tail=head;
}
else
{
tail->next=p;
tail=tail->next;
}
}
#ifdef DEBUG_DESTRUCTORS
~Match(void)
{
if(head!=NULL)
{
cout<<"match deleted"<<endl;
}
}
#endif
};
typedef struct Match match;
struct Matchlist
{
struct Match *head;
struct Match *tail;
Matchlist(void)
{
head=NULL;
tail=NULL;
}
void addmatch(struct Match *m)
{
if(head==NULL)
{
head=m;
tail=head;
}
else
{
tail->next=m;
tail=tail->next;
}
}
#ifdef DEBUG_DESTRUCTORS
~Matchlist()
{
cout<<"Matchlist deleted"<<endl;
}
#endif
};
typedef struct Matchlist matchlist;
|
These are contained in a
deque <matchlist> matches;
These are constructed dynamically during a DNA data mining algorithm with a pointer to a match object; The new match object has its next==NULL at all times while it is being constructed, if the match passes muster it is stored in the matchlist using the addmatch member function.
As the list inside a match object is being built, posnodes are created whenever new positions are found that are part of the match and are stored in the match object using its addpos member function.
Any references made to the master list are access-only, the only time any of these things faces deletion is when the match is being checked before it is added to the matchlist in the deque or at the end of the program.
The key to my worry about memory leaks lies in the potential for the new match object to NOT pass the requirements and need to be deleted. At that point I need to make sure all the attached posnodes are cleaned up, and as long as the deletion can procede from head to tail, no references will remain.