Simple Linked List in C. Segmentation Fault 11 - c

I'm new to C and this language is confusing me a bit.
I keep getting a segmentation fault 11 when running my quite simple linked list code:
struct node{
int val;
struct node *next;
};
struct node *init(){
struct node *l = NULL;
return l;
}
struct node *newNode(int val){
struct node* n = init();
n = (struct node*) malloc(sizeof(struct node));
n->val = val;
n->next=NULL;
return n;
}
void append(struct node* h, int val){
struct node *temp;
temp = h;
int i = 0;
while(temp->next != NULL){
temp = temp->next;
i++;
}
printf("TestAppend");
temp= newNode(val);
}
int main(){
struct node* l = init();
printf("Test1\n");
append(l, 15);
printf("Test2\n");
struct node* temp = init();
temp = l;
}
can someone please explain why?
Thanks :)

Try to change init function to:
struct node *init()
{
void* p = malloc(sizeof(struct node));
return (struct node*)p;
}
Edit:
and free it at the end! – Woodrow Barlow
The segmentation fault is because your code is pointing to NULL.

If you replace calls to init() with simple NULL (which is what it is), you will see for yourself that append tries to use NULL->next.

In append, you should check for 'temp!=NULL' first to avoid the seg fault. Also you are declaring an unnecesary local variable which you are not using at all.

Related

Segmentation fault w/ pointer to pointer in different struct in C

I'm trying to create a priority queue linked list, but keep running into segmentation fault.
My structure definitions are below
typedef struct node {
char *new_element;
struct node *next;
int priority;
} Qnode;
typedef struct {
Qnode *top;
Qnode *tail;
int size;
} Priority_queue;
int main() {
Priority_queue q;
init(&q);
enqueue(&q, "hi", 1);
return 0;
}
void init(Priority_queue *const q) {
q->top = NULL;
q->tail = NULL;
q->size = 0;
return 0;
}
And my enqueue method where the error is caused below
void enqueue(Priority_queue *const q, const char new_element[], int priority) {
/*......*/
Qnode *newNode = (Qnode*) malloc(sizeof(Qnode));
q->tail->next = newNode; /*causes segmentation fault*/
q->tail = newNode; /*doesn't cause segmentation fault*/
/*.......*/
}
I'm guessing I'm not dynamically allocating my memory correctly, but the way my function is written, I'm pointing from one struct to the next so is there a way to fix this?
In your code, init() initializes q->tail with NULL. And you are trying to do q->tail->next = newNode. In case of first node it will essentially means NULL->next = newNode. This is the reason of segmentation fault.
Your enqueue() should be like :
void enqueue(Priority_queue *const q, const char new_element[], int priority) {
/*......*/
Qnode *newNode = (Qnode*) malloc(sizeof(Qnode));
if (q->tail) { /*Do this, only When first node is already allocated*/
q->tail->next = newNode;
}
q->tail = newNode;
/*.......*/
}

segmentation fault(core dumped) codeblocks

I cannot understand why I keep getting the segmentation fault.
I use codeblocks and it compiles successfully, but the code doesn't execute. At the the time of execution, I keep getting this error.
This is my code:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *nc(int data)
{
struct node *temp = (struct node *)(malloc(sizeof(struct node)));
temp->data = data;
temp->next = NULL;
return temp;
}
int main()
{
struct node *head;
head->data = 5;
struct node *a = nc(19);
struct node *b = nc(25);
struct node *c = nc(12);
head->next = a;
a->next = b;
b->next = c;
while (head != NULL)
{
printf("%d \n", head->data);
head = head->next;
}
}
struct node *head;
"head" is NULL at this point.
You have to allocate memory like you did in the case of "temp".
struct node *head = (struct node *)(malloc(sizeof(struct node)));

Segmentation fault while trying to insert node into a linked list

I started learning C programming a few days ago through the book, Programming in C, and I have prior knowledge of java. Inserting a node into a linked list is very easy in java, but I thought if I could do the same in C.
So, I came up with this program,
#include "node.h"
void insertEntry(struct node* root, struct node* after)
{
struct node* first = root;
while(first != (struct node*) 0)
{
if(first->value == after->value)
{
struct node ins;
ins.value = 3456;
ins.next = first->next;
first->next = &ins;
}
first = first->next;
}
}
int main(void)
{
struct node n1, n2, n3;
struct node* list_pointer = &n1;
n1.value = 100;
n1.next = &n2;
n2.value = 200;
n2.next = &n3;
n3.value = 300;
n3.next = (struct node*) 0;
void insertEntry(struct node* root, struct node* after);
while (list_pointer != (struct node*) 0)
{
printf("%i\n", list_pointer->value);
list_pointer = list_pointer->next;
}
printf("\n");
list_pointer = &n1;
insertEntry(list_pointer, &n2);
while (list_pointer != (struct node*) 0)
{
printf("%i\n", list_pointer->value);
list_pointer = list_pointer->next;
}
return 0;
}
node.h
#include <stdio.h>
struct node
{
int value;
struct node* next;
};
Basically, this program takes pointer to the first element of the linked list and the pointer to the element after which it is to be inserted, and inserts a new node after this node.
But when I run this, my program crashes and I cannot find where or why this error occurs.
I looked over to the code in java and tried to implement the same in C.
Thank you.
Here's your problem:
{
struct node ins; // You create an object in the stack
ins.value = 3456;
ins.next = first->next;
first->next = &ins; // You reference your object
} // Your object is popped out of the stack and ceases to exist
// Any access to first->next past this block may cause segfault
In order to avoid this, you could create ins with malloc(), but beware: this isn't java and you have to keep track of all objects you allocated in the heap yourself.
The main problem is you insert a node that is allocated on the stack -- it's invalid as soon as the function is left. To allocate new memory, you need malloc() (don't forget to free() when done, there is no garbage collection).
A few side notes:
It's utterly pointless to cast 0 when used as a pointer to any specific pointer type ... 0 is 0.
You don't need the root node for inserting, so why pass it in the first place?
declaring a prototype inside of a function (in that case: main) doesn't make too much sense ... it will work without because the function you want to call is already defined in the same file.
#include headers where they are needed! node.h doesn't need stdio, the main program does.
A version of roughly your program that would work:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct node
{
int value;
struct node *next;
};
struct node *insertEntry(struct node* after, int val)
{
assert(after); /* not NULL */
struct node *new = malloc(sizeof(struct node));
new->value = val;
new->next = after->next;
after->next = new;
return new;
}
void freeNodeList(struct node* root)
{
struct node *current, *last;
current = root;
while (current)
{
last = current;
current = current->next;
free(last);
}
}
int main(void)
{
struct node *n1, *n2, *n3;
struct node *ptr;
n1 = malloc(sizeof(struct node));
n2 = malloc(sizeof(struct node));
n3 = malloc(sizeof(struct node));
n1->value = 100;
n1->next = n2;
n2->value = 200;
n2->next = n3;
n3->value = 300;
n3->next = 0;
insertEntry(n2, 250);
ptr = n1;
while (ptr)
{
printf("%d\n", ptr->value);
ptr = ptr->next;
}
freeNodeList(n1);
return 0;
}
You should read up on gdb and how to use it.
gcc -Wall -O0 -g x.c -o x
x being your program to compile with debuging information and no optimisation.
then run your program through gdb to find the location/occurrence of the fault.
ie.
gdb x

C Segmentation fault (core dumped)

Hey i am starting to work on Huffman coding and I have a bit of a problem I getting this error
Segmentation fault (core dumped)
I understand it is caused by trying to reach memory you are not allow to but I can not realize what is the problem in my code, thank in advnace for the help!
src.txt - http://pastebin.com/kDf8nEhV
#include <stdio.h>
#include <stdlib.h>
int freq[256] = {0};
struct Node {
unsigned char m_ch;
int m_freq;
struct Node* m_ls, *m_rs;
struct Node* m_hls, *m_hrs;
};
struct Node* createNode(int freq, char ch);
void insertTree(struct Node** root, struct Node* n);
struct Node* getBinTree(FILE* fsrc);
void inorder(struct Node* root);
int main() {
FILE* fsrc;
struct Node* tree = (struct Node*)malloc(sizeof(struct Node));
fsrc = fopen("src.txt", "rb");
tree = getBinTree(fsrc);
inorder(tree);
return 1;
}
struct Node* createNode(int freq, char ch) {
struct Node* pNode = (struct Node*)malloc(sizeof(struct Node));
pNode->m_freq = freq;
pNode->m_ch = ch;
return pNode;
}
void insertTree(struct Node** root, struct Node* n) {
if (!(*root)) {
*root = n;
return;
}
if (n->m_freq < (*root)->m_freq) {
insertTree(&(*root)->m_ls, n);
} else {
insertTree(&(*root)->m_rs, n);
}
}
struct Node* getBinTree(FILE* fsrc) {
struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
struct Node** root = (struct Node**)malloc(sizeof(struct Node*));
*root = (struct Node*)malloc(sizeof(struct Node));
int c, i;
while ((c = fgetc(fsrc)) != EOF) {
freq[c]++;
}
freq[255] = 1;
fclose(fsrc);
for (i = 0; i < 256; i++) {
if (freq[i] > 0) {
temp = createNode(freq[i], i);
insertTree(root, temp);
}
}
}
void inorder(struct Node* root) {
if (root != NULL) {
inorder(root->m_ls);
printf(" %d\n", root->m_freq);
inorder(root->m_rs);
}
return;
}
Your,
struct Node* getBinTree(FILE *fsrc)
is not returning anything.
You should enable compiler warnings, the compiler would have told you about that, the function is not returning a value, but you still assign it to tree in main().
But apart from that there is a serious problem with your code, a simple example
int main()
{
FILE *fsrc;
struct Node *tree = (struct Node*)malloc (sizeof(struct Node));
fsrc = fopen("src.txt","rb");
tree=getBinTree(fsrc);
inorder(tree);
return 1;
}
This single function has many problems,
You allocate new memory and point to it with tree, but you never use it because you overwrite the pointer here
tree = getBinTree(fsrc);
that causes a memory leak.
You don't check if the file was succesfuly opened, you must check
fsrc = fopen("src.txt", "rb");
if (fsrc == NULL)
return -1;
You don't need to cast malloc()
struct Node *tree = malloc(sizeof(*tree));
this is more robust, and easier to read.
You have to make sure that malloc() did not fail to allocate memory, when it does NULL is returned, so you need this when you do a malloc() that is actually required, for example in getBinTree()
struct Node *tree = malloc(sizeof(*tree));
if (tree == NULL)
return NULL;
i.e., copy malloc()'s behavior by returning NULL on failure.

reverse linked list in C using recursion

I have written following code in C. I am pretty new to C. The insert and Print functions seem to work fine but I get a prompt that says program stopped working when I call Reverse function.
Where dis I go wrong ?
//WAP to reverse a Linked List using recursion
#include<stdio.h>
#include<stdlib.h>
struct Node{
int data;
struct Node* next;
};
struct Node* head; //global variable
struct Node* Reverse(struct Node* p){
if(p->next == NULL){ //since for last node link part is null
head = p;
printf("break condition");
return head;
}
printf("calling reverse");
Reverse(p->next);
struct Node* q = p->next;
q->next = p;
p->next = NULL;
}
void Insert(int x){
struct Node* temp= (struct Node*)malloc(sizeof(struct Node));
temp->data = x;
//temp->next = NULL; //redundant
//if(head!= NULL){
temp->next = head; //temp.next will point to null when head is null nd otherwise what head was pointing to
//}
head = temp;
}
void Print(){
struct Node* temp1 = head; //we dont want tomodify head so store it in atemp. bariable and then traverse
while(temp1 != NULL){
printf(" %d", temp1->data);
temp1= temp1->next;
}
printf("\n");
}
int main(){
struct Node* head = NULL;
Insert(2);
Insert(4);
Insert(5);
Insert(1);
Print();
head = Reverse(head);
// Print();
}
There are two issues with the program above:
1) You have two head variables. One is a global variable, and the other is a variable local to the main function. That local variable is the one that is passed to Reverse(). Since the first thing that function does is dereferencing it, the program crashes. Removing the local head variable in the main() function should address it.
2) The Reverse() function correctly returns head when it reaches the exit condition, but what happens the rest of the time? It's missing a return in the non-exit condition case. Here's a diff that would address the issue:
printf("calling reverse");
- Reverse(p->next);
+ struct Node* ret;
+ ret = Reverse(p->next);
struct Node* q = p->next;
q->next = p;
p->next = NULL;
+ return ret;

Resources