Reputation: 23
Here is a simple implementation of a singly-linked list with create()
,addnode()
and destroy()
functions. After I called the destroy function, I printed head->val
, which should give a segmentation fault, as the memory is freed. However, this only happens in debug mode. If I build and run, the program has no issue printing the head and even the entire list.
Any ideas on why debugging and building give different outcomes? Thanks!
#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct sllist{
int val;
struct sllist* next;
}
sllnode;
sllnode* create(int value)
{
sllnode* p =(sllnode*) malloc(sizeof(sllnode));
if(p == NULL)
return NULL;
p->val=value;
p->next=NULL;
return p;
}
sllnode* addnode(sllnode* head, int value)
{
sllnode* p =(sllnode*) malloc(sizeof(sllnode));
if(p == NULL)
return NULL;
p->val=value;
p->next=head;
return p;
}
void destroy(sllnode* head){
if(head == NULL)
return;
destroy(head->next);
free(head);
}
int main()
{
sllnode* head = create(6);
for(int i=1;i<=5;++i)
{
head=addnode(head,i+1);
}
sllnode* p = head;
while(p != NULL)
{
cout<<p->val;
p=p->next;
}
cout<<"\n"<<head<<"\n";
destroy(head);
cout<<head->val;
return 0;
}
Upvotes: 0
Views: 50
Reputation: 213809
After I called the destroy function, I printed head->val, which should give a segmentation fault, as the memory is freed.
You are mistaken: accessing freed memory almost never results in a segmentation fault.
why debugging and building give different outcomes?
Debugging allocators often overwrite freed memory with an easily recognizable pattern, such as 0xCDCDCDCDCD...
or 0xDEADBEEF...
. Reading such memory still does not result in a segmentation fault, but dereferencing a pointer residing in freed memory does (that's the purpose of overwriting freed memory).
Upvotes: 2