I have a linked list that I'm attempting to turn into a "heap" that stores its content dynamically. I thought that my delete_node
function was working properly but when I try to heapify the list I get a segmentation fault.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node {
int content;
struct Node* next;
};
struct Heap {
char* type;
int* array;
int head;
int tail;
int heap_capicity;
};
struct Node* add(struct Node* list, int x) {
if (list == NULL) {
struct Node* new_nd = malloc(sizeof(struct Node));
new_nd->content = x;
new_nd->next = NULL;
return new_nd;
}
list->next = add(list->next, x);
return list;
}
struct Node* delete_node(struct Node* node, int x) {
if (node == NULL || node->next == NULL) return NULL;
if (node->next->content == x) {
struct Node* temp = node->next;
node->next = node->next->next;
// temp = NULL;
free(temp);
return node;
}
node->next = delete_node(node->next, x);
return node;
}
struct Heap* new_heap(char* type) {
struct Heap* new_heap = malloc(sizeof(struct Heap));
new_heap->type = type;
new_heap->array = malloc(2 * sizeof(int));
new_heap->array[0] = 0;
new_heap->head = -1;
new_heap->tail = -1;
new_heap->heap_capicity = 2;
return new_heap;
}
void double_it(struct Heap* heap) {
heap->array = realloc(heap->array, heap->heap_capicity * 2);
heap->heap_capicity *= 2;
return;
}
void add_hp(struct Heap* heap, int content) {
if (heap->head < 0) {
heap->head = 1;
heap->tail = 1;
heap->array[heap->head] = content;
return;
}
if (heap->tail + 1 == heap->heap_capicity) double_it(heap);
heap->array[++heap->tail] = content;
// swim(&heap, heap->tail);
return;
}
void heapify_from_linked_list(struct Heap* heap, struct Node* node) {
if (node == NULL) return;
add_hp(heap, node->content);
heapify_from_linked_list(heap, node->next);
return;
}
int main () {
struct Node* my_list = NULL;
my_list = add(my_list, 1);
my_list = add(my_list, 2);
my_list = add(my_list, 3);
my_list = add(my_list, 4);
my_list = add(my_list, 5);
my_list = add(my_list, 6);
my_list = add(my_list, 7);
my_list = add(my_list, 8);
my_list = add(my_list, 9);
my_list = add(my_list, 10);
delete_node(my_list, 7);
struct Heap* maxPQ = new_heap("max");
heapify_from_linked_list(maxPQ, my_list);
return 0;
}
OUTPUT:
[1000, 100, 10, 1, 11, 111, 1111, 636, 422, 838, 166, 799, 945, 506, 676, 454, 677]
Deleting 111
[1000, 100, 10, 1, 11, 1111, 636, 422, 838, 166, 799, 945, 506, 676, 454, 677]
Calling heapify
Node is: 1000
Node is: 100
Node is: 10
Node is: 1
Node is: 11
Node is: 1
Segmentation fault: 11
Weirdly enough, some of the values can be removed with no issue, for instance 1 can be removed and the program runs fine. I found that the issue was me not nullifying the pointer before freeing it. My question is, although I know it's good practice to nullify pointers that are not in use, why would the next pointer of a node point to an arbitrary node in one case (when heapify is called) but not another (when delete_node is called)?