I was trying to make a linked list using «Object Oriented» C. But I do not know how to backtrace segmentation fault, so I cannot find the solution.
Libraries, you know...
#include <stdio.h>
#include <stdlib.h>
Within the structure I have two pointers to functions. These pointers mimic methods (something like that).
struct nodeList {
int data;
struct nodeList * nextPtr;
void (*print)(struct nodeList *);
void (*insert)(struct nodeList **, int);
int (*delete)(struct nodeList **, int);
};
You know, I hate write struct every time.
typedef struct nodeList NodeList;
typedef NodeList * NodeListPtr;
Prototypes declarations. init is something like a constructor. I do not need a destructor, the function free() handles that.
NodeListPtr init(int);
void print(NodeListPtr);
void insert(NodeListPtr *, int);
int delete(NodeListPtr *, int);
int main(void)
{
NodeListPtr myList = init(0);
myList->insert(&myList, 5);
Here is where the segmentation fault happens :(
myList->insert(&myList, 3);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
myList->print(myList);
free(myList);
return 0;
}
Function declarations, you know. init is, like I said, something like a constructor. It returns an instance of NodeListPtr with the pointer funcions pointing to the rest of the functions.
NodeListPtr init(int data)
{
NodeListPtr instance = (NodeListPtr) malloc(sizeof(NodeListPtr));
instance->data = data;
instance->nextPtr = NULL;
instance->print = &print;
instance->insert = &insert;
instance->delete = &delete;
return instance;
}
Iterates over the list and prints all data.
void print(NodeListPtr listPtr)
{
NodeListPtr currentPtr = listPtr;
while(currentPtr != NULL) {
printf("%d -> ", currentPtr->data);
currentPtr = currentPtr->nextPtr;
}
puts("(NULL)");
}
Inserts an element in an orderly manner.
void insert(NodeListPtr *selfPtr, int value)
{
NodeListPtr newPtr;
NodeListPtr previousPtr;
NodeListPtr currentPtr;
newPtr = init(value);
if(newPtr != NULL) {
previousPtr = NULL;
currentPtr = *selfPtr;
while(currentPtr != NULL && value > currentPtr->data) {
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
if(previousPtr == NULL) {
newPtr->nextPtr = *selfPtr;
*selfPtr = newPtr;
} else {
previousPtr->nextPtr = newPtr;
newPtr->nextPtr = currentPtr;
}
} else {
printf("Could not add %d. No memory available\n", value);
}
}
Deletes an element of the list. If it does not exist, return null character.
int delete(NodeListPtr *selfPtr, int data)
{
NodeListPtr tempPtr;
NodeListPtr currentPtr;
NodeListPtr previousPtr;
if((*selfPtr)->data == data) {
tempPtr = *selfPtr;
*selfPtr = (*selfPtr)->nextPtr;
free(tempPtr);
return data;
} else {
previousPtr = *selfPtr;
currentPtr = (*selfPtr)->nextPtr;
while(currentPtr != NULL && currentPtr->data != data) {
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
if(currentPtr != NULL) {
tempPtr = currentPtr;
previousPtr->nextPtr = currentPtr->nextPtr;
free(tempPtr);
return data;
}
}
return '\0';
}
And that's it. Like I said, I do not know how to do backtrace over segmentation fault with GDB, so I do not know how to fix it.
NodeListPtr instance = (NodeListPtr) malloc(sizeof(NodeListPtr));-->NodeListPtr instance = (NodeListPtr) malloc(sizeof(NodeList));