Niels
Niels

Reputation: 597

free causes segmentation fault in C

In the following program, which is intended only for educational purposes, I cannot see why free() causes a segmentation fault. In the last loop I try to clean op my double-connected pointer list but even a single free() on the first_node (outside the loop if I place it there) results in a segmentation fault... Does any body see why?

#include <stdio.h>
#include <stdlib.h>

typedef struct Node Node;

struct Node {
    Node *prev;
    Node *next;
    int val;
};

int main() {
    Node *first_node;
    Node *active_node;
    Node *prev_node;
    first_node->val = 0;
    active_node = first_node;
    for (int c = 1; c < 10 ; c = c + 1) {
        active_node->next = (Node *)malloc(sizeof(Node));
        active_node->next->val = c;
        active_node->next->prev = active_node;
        prev_node = active_node;
        active_node = active_node->next;
    }
    active_node = first_node;
    while (active_node) {
        printf("Node: %d\n", active_node->val);
        prev_node = active_node;
        active_node = active_node->next;
    }

    active_node = first_node;
    while (active_node) {
        prev_node = active_node;
        active_node = active_node->next;
        free(prev_node); 
    }
    return 0;
}

I am sure it is the free() as when I comment that line out, the program runs fine.

My output looks like this:

Node: 0
Node: 1
Node: 2
Node: 3
Node: 4
Node: 5
Node: 6
Node: 7
Node: 8
Node: 9
Segmentation fault (core dumped)

Upvotes: 2

Views: 267

Answers (1)

chqrlie
chqrlie

Reputation: 145297

first_node is uninitialized when you perform first_node->val = 0;. active_node receives the value of this uninitialized pointer and is used for the last node of the list.

It is actually surprising that the program runs at all, you have undefined behavior on the first statement of the main() function.

Just initialize active_node to NULL and fix the intialization code:

#include <stdio.h>
#include <stdlib.h>

typedef struct Node Node;

struct Node {
    Node *prev;
    Node *next;
    int val;
};

int main() {
    Node *first_node;
    Node *active_node;
    Node *prev_node;

    first_node = prev_node = NULL;
    for (int c = 0; c < 10; c = c + 1) {
        Node *new_node = (Node *)malloc(sizeof(Node));
        if (new_node == NULL)
            return 1;
        new_node->val = c;
        new_node->prev = prev_node;
        new_node->next = NULL;
        if (prev_node)
            prev_node->next = new_node;
        else
            first_node = new_node;
        prev_node = new_node;
    }

    active_node = first_node;
    while (active_node) {
        printf("Node: %d\n", active_node->val);
        active_node = active_node->next;
    }

    active_node = first_node;
    while (active_node) {
        prev_node = active_node;
        active_node = active_node->next;
        free(prev_node); 
    }
    return 0;
}

Upvotes: 2

Related Questions