I've made a very simple linked list node structure in C, with some generic pointer data and a pointer to the next node structure. I have a function which will take a linked list node, and delete it as well as any other node it links to. It is currently made like this:
void freeLinkedList(LinkedListNode *node)
{
LinkedListNode *currentNode = node;
LinkedListNode *previousNode = NULL;
do
{
free(currentNode->data);
previousNode = currentNode;
currentNode = currentNode->next;
printf("Freeing node... %s\n", previousNode->name);
free(previousNode);
printf("freed it!\n");
} while (currentNode != NULL);
printf("Deleted node and all referencing nodes!");
}
It very simply traverses from the node given in the function, and continues to delete the pointer data, point to the next node pointed to (if any), then delete memory for the previous node. This does work as predicted... but only in some cases.
The actual LinkedList structure looks like this:
typedef struct LinkedListNode {
void *data;
struct LinkedListNode *next;
char name[50];
} LinkedListNode;
In the case of structures dynamically allocated like this, the function works perfectly:
LinkedListNode *myNode1 = malloc(sizeof(struct LinkedListNode));
LinkedListNode *myNode2 = malloc(sizeof(struct LinkedListNode));
LinkedListNode *myNode3 = malloc(sizeof(struct LinkedListNode));
strcpy(myNode1->name, "Node1");
myNode1->data = NULL;
myNode1->next = myNode2;
strcpy(myNode2->name, "Node2");
myNode2->data = NULL;
myNode2->next = myNode3;
strcpy(myNode3->name, "Node3");
myNode3->data = NULL;
myNode3->next = NULL;
freeLinkedList(myNode1); // CALLING DELETE FUNCTION HERE
But if I use the function with structures allocated not on heap memory, but instead automatic stack memory like so:
LinkedListNode myNode1 = {NULL, NULL, "Node1"};
LinkedListNode myNode2 = {NULL, NULL, "Node2"};
LinkedListNode myNode3 = {NULL, NULL, "Node3"};
myNode1.next = &myNode2;
myNode2.next = &myNode3;
freeLinkedList(&myNode1); // CALLING DELETE FUNCTION HERE
I get a SIGSEGV - segmentation fault at this line in the function:
free(previousNode);
This error ONLY happens at the free function of the last node, that is, the output will say: "Freeing node... node3
Then crash.
But the very funny thing is, so far I've only experienced it using the example above. If I say, declare one more local LinkedListNode struct like this:
LinkedListNode myNode1 = {NULL, NULL, "Node1"};
LinkedListNode myNode2 = {NULL, NULL, "Node2"};
LinkedListNode myNode3 = {NULL, NULL, "Node3"};
LinkedListNode myNode4 = {NULL, NULL, "Node4"};
myNode1.next = &myNode2;
myNode2.next = &myNode3;
freeLinkedList(&myNode1);
The function actually works, and does everything as expected to.
I've tried for a couple of hours now to think of why this could be, but I'm simply stumped. Does it have something to do with me attempting to free memory allocated on the stack?
You're a victim of Undefined behavior
which is caused due to freeing of stack memory
.
Which can prove out to be fatal and sometimes seem to work.
This has already been answered in this thread free() on stack memory that should explain it all.