'Having Issues with Segmentation Error in Doubly Linked List Implementation
I'm pretty new to C and I can't figure out why I'm getting a segmentation fault from this code:
void delete_list(LIST *list)
{
NODE* n = list->head;
while(n != list->tail)
{
NODE* next = n->next;
free(n);
n = next;
}
free(n);
free(list);
}
I'm pretty certain this is the part of my code that's has the error, but if not I can post the rest of my code. Both NODE and LIST are created using malloc(). The code is the barebones framework for a doubly-linked-list.
EDIT 2: Here's the code to reproduce what I'm doing. Very basic test case but it is failing. First is the header file list.h, then the main file list.c. I also eradicated the first edit to clean up the question a bit.
#ifndef __LIST_H__
#define __LIST_H__
typedef struct node {
char *value; /* Pointer to the string we are storing. */
struct node *previous; /* Pointer to the preceding node in the list. */
struct node *next; /* Pointer to the next node in the list. */
} NODE;
typedef struct list {
NODE *head; /* Pointer to the first node in the list. */
NODE *tail; /* Pointer to the last node in the list. */
} LIST;
/* Function prototypes the public interface. */
LIST *new_list(const char *value);
void prepend(LIST *list, const char *value);
void append(LIST *list, const char *value);
void delete_list(LIST *list);
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "list.h"
NODE *new_node(const char *value);
LIST *new_list(const char *value)
{
LIST *list = (LIST*) malloc(sizeof(LIST));
NODE* n = new_node(value);
list->head = n;
list->tail = n;
return list;
}
void prepend(LIST *list, const char *value)
{
NODE* n = new_node(value);
n->next = list->head;
list->head->previous = n;
list->head = n;
}
void append(LIST *list, const char *value)
{
NODE* n = new_node(value);
n->previous = list->tail;
list->tail->next = n;
list->tail = n;
}
void delete_list(LIST *list)
{
NODE* n = list->head;
while(n != list->tail)
{
NODE* next = n->next;
free(n);
n = next;
}
free(n);
free(list);
}
NODE *new_node(const char *value)
{
NODE *node = (NODE*) malloc(sizeof(NODE));
node->value = (char*) malloc((strlen(value) + 1) * sizeof(char));
strcpy(node->value, value);
node->previous = NULL;
node->next = NULL;
return node;
}
void print_list(const LIST *list)
{
/* Print the contents of a list. */
for (NODE *node = list->head; node != NULL; node = node->next) {
printf("%s\n", node->value);
}
}
int main()
{
char *middle = "middle";
char *last = "last";
char *first = "first";
LIST* list = new_list(middle);
prepend(list, first);
append(list, last);
print_list(list);
delete_list(list);
print_list(list);
}
Solution 1:[1]
You obviously can't
delete_list(list);
print_list(list);
The list is gone after delete. (you invoke Undefined Behavior at that point) The only other issue you have is you fail to free()
node->value
.
You can fix that with:
void delete_list(LIST *list)
{
NODE* n = list->head;
while(n != list->tail)
{
NODE* next = n->next;
free(n->value);
free(n);
n = next;
}
free (n->value);
free(n);
free(list);
}
Your code works fine then.
Memory Use/Error Check
$ valgrind ./bin/list
==9065== Memcheck, a memory error detector
==9065== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==9065== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==9065== Command: ./bin/list
==9065==
first
middle
last
==9065==
==9065== HEAP SUMMARY:
==9065== in use at exit: 0 bytes in 0 blocks
==9065== total heap usage: 8 allocs, 8 frees, 1,130 bytes allocated
==9065==
==9065== All heap blocks were freed -- no leaks are possible
==9065==
==9065== For counts of detected and suppressed errors, rerun with: -v
==9065== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Alternative Delete List
You may find the following alternative for delete_list()
a bit more readable -- up to you:
void delete_list (LIST *list)
{
NODE *n = list->head;
while (n) {
NODE *victim = n;
n = n->next;
free (victim->value);
free (victim);
}
free (list);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |