Segmentation fault w/ pointer to pointer in different struct in C - 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;
/*.......*/
}

Related

I'm having a problem creating a linked list [duplicate]

This question already has answers here:
Linked lists - single or double pointer to the head
(3 answers)
What is the reason for using a double pointer when adding a node in a linked list?
(15 answers)
Closed 10 months ago.
#include<stdio.h>
#include<stdlib.h>
void insert_front(struct node* head, int block_number);
void insert_rear(struct node* head, int block_number);
void print_list(struct node* head);
struct node {
int block_number;
struct node* next;
};
int main(void)
{
struct node* list = NULL;
insert_front(list, 10);
insert_rear(list, 20);
insert_front(list, 30);
insert_rear(list, 40);
print_list(list);
return 0;
}
void insert_front(struct node* head, int block_number)
{
struct node* p = malloc(sizeof(struct node));
p->block_number = block_number;
p->next = head;
head = p;
return head;
}
void insert_rear(struct node* head, int block_number)
{
struct node* p = malloc(sizeof(struct node));
p->block_number = block_number;
p->next = NULL;
if (head == NULL) {
head = p;
}
else {
struct node* q = head;
while (q->next != NULL) {
q = q->next;
}
q->next = p;
}
}
void print_list(struct node* head)
{
struct node* p = head;
while (p != NULL) {
printf("--> %d ", p->block_number);
p = p->next;
}
printf("\n");
}
When I ran it, there was no result at all.
Now, in the insert_front function p->block_number = block_number, a message appears saying that the NULL pointer 'p' is being dereferenced... (The same thing appears in the insert_rear function.)
Could it be that I am declaring the pointer wrong?
Both insert_front and insert_rear need to convey possibly head modification back to the caller, and the caller needs to reap that information. Both should be declared to return struct node *, do so, and the code in main react accordingly. E.g.:
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
struct node * insert_front(struct node *head, int block_number);
struct node * insert_rear(struct node *head, int block_number);
void print_list(struct node *head);
struct node
{
int block_number;
struct node *next;
};
int main(void)
{
struct node *list = NULL;
list = insert_front(list, 10);
list = insert_rear(list, 20);
list = insert_front(list, 30);
list = insert_rear(list, 40);
print_list(list);
return 0;
}
struct node *insert_front(struct node *head, int block_number)
{
struct node *p = malloc(sizeof(struct node));
p->block_number = block_number;
p->next = head;
head = p;
return head;
}
struct node *insert_rear(struct node *head, int block_number)
{
struct node *p = malloc(sizeof(struct node));
p->block_number = block_number;
p->next = NULL;
if (head == NULL)
{
head = p;
}
else
{
struct node *q = head;
while (q->next != NULL)
{
q = q->next;
}
q->next = p;
}
return head;
}
void print_list(struct node *head)
{
struct node *p = head;
while (p != NULL)
{
printf("--> %d ", p->block_number);
p = p->next;
}
printf("\n");
}
Output
--> 30 --> 10 --> 20 --> 40
I leave the memory leaks for you to resolve.
In C all variables are passed by value – if you pass a pointer, then it is copied, too (not the pointed to object, of course...), and function parameters, apart from being initialised from outside, are nothing more than local variables. Thus via head = p; you just assign the local copy of the outside pointer, not the latter itself!
To fix that you have two options:
Return the new head and make the user responsible for re-assigning the returned value to his own head pointer.
Accept the head as pointer to pointer.
With second approach a user cannot forget to re-assign the (potentially) new head, so that's what I'd go with:
void insert_whichEver(node** head, int block_number)
{
// use `*head` where you had `head` before...
}
void demo()
{
node* head = NULL;
insert_front(&head, 1012);
}
And in insert_front drop return head;, a function with void cannot return anything concrete and does not require a return at all (but bare return; can be used to exit a function prematurely).

Simple Linked List in C. Segmentation Fault 11

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.

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)));

C Segmentation Fault (core dumped) Linked List

I keep getting Segmentation Fault (core dumped) run time error and I can't figure out why.
My code:
struct Node
{
void *next;
void *val;
};
typedef struct Node* NodePtr;
struct List
{
NodePtr head;
};
typedef struct List* ListPtr;
ListPtr create()
{
ListPtr ptr = malloc(sizeof(struct List));
return ptr;
}
int insert(ListPtr list, void *obj)
{
NodePtr newObj = malloc(sizeof(struct Node));
//Cast next as a self referencing Node
newObj->next = (NodePtr) newObj->next;
//Point to beginning of list
NodePtr current = list->head;
if(list->head == NULL)
{
newObj->val = obj;
list->head->next = newObj;
newObj->next = NULL;
return 1;
}
return 0;
}
int main(int argc, char *argv[])
{
int x = 2;
int *p = &x;
ListPtr thing = create();
insert(thing, p);
return 0;
}
The error is here: list->head->next = newObj after some debugging. I thought I had to allocate memory for list->head->next, but when I added the code in for that it still gave me the same error. Am I casting it wrong or not allocating memory correctly? Any help would be appreciated, thanks!
Just put this together, runs fine.
#include <stdlib.h>
#include <stdio.h>
struct Node {
void *next;
void *val;
};
typedef struct Node* NodePtr;
struct List {
NodePtr head;
};
typedef struct List* ListPtr;
ListPtr CreateList() {
ListPtr ptr = malloc(sizeof(struct List));
return ptr;
}
void Insert(ListPtr list, void *obj) {
// create and initialize new node
NodePtr newObj = malloc(sizeof(struct Node));
newObj->val = obj;
newObj->next = NULL;
//Point to beginning of list
NodePtr curr = list->head;
// Add node to the list
if(curr == NULL) // if no head node, make newObj the head node
{
list->head = newObj;
}
else{ // otherwise traverse the list until you find the last node (the one that points to a null as the next)
while(1) {
if(curr->next != NULL) {
curr = curr -> next;
} else {
curr->next = newObj;
}
list->head = newObj;
newObj->val = obj;
list->head->next = newObj;
newObj->next = NULL;
}
}
}
int main() {
int x = 2;
int *p = &x;
ListPtr thing = CreateList();
Insert(thing, p);
return 0;
}
You check if list->head is NULL and then do some operations with that. Change that to if(list->head != NULL)
{
...
}
At a thought, malloc does not guarantee allocated memory is empty. It's good practice to set all values where they matter after allocation.
list->head is probably not null
also : newObj->next = (NodePtr) newObj->next;
doesn't set to a rational value, it sets to whatever memory was set - were you intending newObj->next = (NodePtr) newObj; ?
list->head should not be referenced if null. list->head->next will only be valid if it's not null.
if you actually want to build a list,
newObj->val = obj;
if (list->head == NULL) { newObj->next = list->head; }
list->head = newObj;
either that or travel down list->head->next chain until next is null, and set that to be newObj->next. If that way then it's possibly a good idea, newObj->next should be set to NULL and not itself.
Might want to figure out how your list will behave - is it circular? does it grow from the head (list->head) or tail (last ->next) ? Do you spot the tail when listObject->next == NULL or when listObject->next == listObject ?
I realize that this answer is mostly stylistic. But I do think that (bad) style and (bad) habits are an (important) part of (bad) programming. Summing it up ...
(in most cases) typedefs are not needed; they just introduce an alias for something that already existed.
[rule of seven] human readers have a limited amount of identifiers ("names") that they can keep track of. This could be 7. Minimising the number of distinct words makes reading easier.
also, the reader has to remember that xPtr and xNode are related (typeof *xPtr === typeof xNode)
when reading source code, keywords and special character tokens (such as operators) don't count as an identifier, since you do not have to remember them. (Syntax-highligting helps, too)
if there is only one way of expressing your program, there is no possibility for errors like iPtr *p; p = (qPtr) malloc (sizeof xNode);
creating yet another struct (+typedefs for it), just to accomodate a root pointer will clobber up your mental namespace even more.
Now a rework of the (intended) code:
#include <stdio.h>
#include <stdlib.h>
struct node {
struct node *next;
void *payload;
};
struct node *root=NULL;
void initialize() { /* nothing .... */ }
int insert(struct node **pp, void *pv) {
struct node *p;
p = malloc(sizeof *p);
if (!p) { /* handle error */ return -1; }
p->payload = pv;
p->next = *pp;
*pp = p;
return 1; /* inserted one element */
}
int main(void)
{
int i;
i=666;
/* note: this function call will pass a pointer to a local variable `i`
** to the insert() function, which will remember it.
** This is generally a bad idea, to say the least.
*/
insert( &root, &i);
return 0;
}

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.

Resources