1

Can anyone explain why do I get "double free or corruption (fasttop)" error in this program right after print_list(head_node)? Before head_node = insert_to_first(head_node, temp);, head_node already points to other node. e.g. head_node -> node1 and what I want is to insert a node before node1 that will be pointed by head_node and that will be pointed to node1. Here's the complete program: (using g++ to compile)

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

typedef struct NODE Node;
struct NODE {
    int data;
    Node* next;
};

Node* create_item(int);
Node* insert_to_first(Node*, Node*);
void print_list(Node*);

int main() {

    struct NODE *head_node;
    struct NODE *temp;

    head_node = create_item(2);
    temp = create_item(5);

    head_node = insert_to_first(head_node, temp);
    print_list(head_node);

    free(head_node);
    free(temp);

    return 0;
}

Node* create_item(int data) {
    Node* new_item = (Node*) malloc(sizeof(Node));

    (*new_item).data = data; // new_item->data = data;
    new_item->next = NULL;

    return new_item;
}

Node* insert_to_first(Node* head_node, Node* item) {
    item->next = head_node;
    return item;
}

void print_list(Node* node) {
    printf("Executing...\n");
    for(; node != NULL; node = node->next) {
        printf("Current list (address):\t%p\n", node);
        printf("Data:\t\t\t%d\n", node->data);
        printf("Next list (address):\t%p\n", node->next);
        printf("-----------------------------------------\n");
    }
    printf("Execution terminated.\n");
}
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • It's because after the line `head_node = insert_to_first(head_node, temp);`, `head_node` points to the same element than `temp`. You should write a `delete_list` function similar to `print_list` that frees each element instead of printing it. – Jabberwocky Apr 19 '18 at 15:53
  • OP, basically your `insert_to_first` function adds to the beginning of the list and returns the newly inserted pointer as the head. When you do: `head_node = insert_to_first(head_node, temp);` both the `head_node` and the `temp` pointers point to the same location. So when you do `free(head_node); free(temp);` this is your double free. Instead, you should write a function that frees the entire list by iterating over it similarly to how you wrote `print_list` – MFisherKDX Apr 19 '18 at 16:00
  • But will `head_node` be pointing to `temp` after `insert_to_first(Node*, Node*)`? – Naruto Uzumaki Apr 19 '18 at 16:20
  • @NarutoUzumaki yes, see my answer below. And you can check that easily yourself. – Jabberwocky Apr 19 '18 at 16:22
  • Possible duplicate of [How to track down a "double free or corruption" error](https://stackoverflow.com/questions/2902064/how-to-track-down-a-double-free-or-corruption-error) – Raedwald Dec 06 '18 at 13:44

1 Answers1

1

Extract of your code:

head_node = create_item(2);
temp = create_item(5);

head_node = insert_to_first(head_node, temp);
// now head_node has changed, it points now to the same location as temp now

free(head_node);  // so here you are not freeing the original head_node, but rather temp
free(temp);       // and here you free temp again, hence the "double free".
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115