Segmentation fault- queue won't initialize - c

The above code throws a segmentation fault and I am racking my brain to see where it is. The queue doesn't get initialized. I have been looking at the code for the longest time and i cannot identify what is going wrong.
typedef struct node node;
struct node
{
int data;
node *link;
};
typedef struct list
{
node *head;
node *tail;
int number_of_nodes;
}s_list;
typedef struct queue
{
s_list *ptr_list;
}queue;
void list_initialize(s_list* ptr_list) //debugger says this line is a problem? But seems fine to me?
{
ptr_list->head=NULL;
ptr_list->tail=NULL;
ptr_list->number_of_nodes=0;
}
void queue_initialize(queue* queue_list)
{
list_initialize(queue_list->ptr_list);
}
int main()
{
queue queue;
queue_initialize(&queue); //Have used a debugger and this isn't succesfull.
}
I cannot change the variable names or structures because this is part of an assignment i am supposed to fill.
I have tried changing the queue_initialization function to:
void queue_initialize(queue* queue_list)
{
queue_list=malloc(sizeof(queue));
list_initialize(queue_list->ptr_list);
}
There is still a segmentation fault

ptr_list is never initialized so in list_initialize() you are writing to random memory. In queue_initialize() you need something like this:
void queue_initialize(queue* queue_list)
{
queue_list->ptr_list = malloc(sizeof(s_list));
list_initialize(queue_list->ptr_list);
}

Related

Why does my queue throw a memory segmentation error when I try to dequeue?

I coded a Queue, the enqueuing function works correctly. It adds the new node to the back of the list. To save time, I used another pointer for the dequeuing method. I used a tail pointer that points to the oldest node. During queue creation(first node), the head pointer is assigned to the tail pointer. After that, in the dequeuing function, the tail pointer becomes its parent, and then the pointer is freed, and then the structure is returned. Now, when I coded a program that tests the queue, when dequeue() is called, it throws a memory segmentation error. Why?
Here's the code of the queue:
#include <stdio.h>
#include <stdlib.h>
/*uncomment the 4th line of size is more important to you than speed. The program will then take
more cpu cycles to read certain members of the structure, but it wont use padding, which wastes memory
but increases speed.*/
//#define SIZE_OVER_SPEED
#ifdef SIZE_OVER_SPEED
#pragma pack(1)
#endif
struct node{
int data;
struct node *next;
struct node *parent;
};
#ifdef SIZE_OVER_SPEED
#pragma pack(0)
#endif
typedef struct node _LINKED_LIST_QUEUE;
void enqueue(int,_LINKED_LIST_QUEUE**,_LINKED_LIST_QUEUE*);
void enqueue(int value, _LINKED_LIST_QUEUE **queue_head, _LINKED_LIST_QUEUE *tail){
if(*queue_head==NULL){
*queue_head=(_LINKED_LIST_QUEUE*)malloc(sizeof(_LINKED_LIST_QUEUE));
if(*queue_head==NULL){
perror("[malloc]");
exit(EXIT_FAILURE);
}
(**queue_head).data=value;
(**queue_head).parent=NULL;
(**queue_head).next=NULL;
tail=*queue_head;
return;
}
_LINKED_LIST_QUEUE *save_head=*queue_head;
*queue_head=(_LINKED_LIST_QUEUE*)malloc(sizeof(_LINKED_LIST_QUEUE));
if(*queue_head==NULL){
perror("[malloc]");
exit(EXIT_FAILURE);
}
(**queue_head).data=value;
(**queue_head).parent=NULL;
(**queue_head).next=save_head;
(*save_head).parent=*queue_head;
}
_LINKED_LIST_QUEUE dequeue(_LINKED_LIST_QUEUE *tail, int *SIGEND){
_LINKED_LIST_QUEUE retstruct=*tail;
if((*tail).parent==NULL){
*SIGEND=1;
}
tail=(*tail).parent;
free((*tail).next);
return retstruct;
}
Here's the code of the tester program.
#include "main.c"
void normal_traverse(_LINKED_LIST_QUEUE *head){
_LINKED_LIST_QUEUE *selected=head;
while(selected!=NULL){
printf("%d\t",(*selected).data);
selected=(*selected).next;
}
puts("");
}
int main(){
_LINKED_LIST_QUEUE *head, *tail;
int end=0;
head=NULL;
enqueue(1,&head,tail);
enqueue(2,&head,tail);
enqueue(3,&head,tail);
enqueue(4,&head,tail);
normal_traverse(head);
printf("%d\n",(dequeue(tail,end)).data);
printf("%d\n",(dequeue(tail,end)).data);
printf("%d\n",(dequeue(tail,end)).data);
printf("%d\n",(dequeue(tail,end)).data);
return 0;
}
#Gerhardh pointed out that the head pointer was being assigned to the local copy of tail'. So, I made tail` a double pointer. That solved my problems.

Linked List Deletion function causing program to crash *wrong pointers?*

In my program when a username is following another one and also has posted a "tweet" which is a string in an attempt to delete the followed username it breaks the program. I believe this is the code snippet in question. If anyone could help me identify the issue I would be thankful as I am learning the usage of linked lists for scale able projects. Thanks
void deleteAccount(accountNodePtr *startPtr, accountNodePtr *curAcPtr, tweetsNodePtr *startTwtPtr){
accountNodePtr acLoopPtr;
accountNodePtr tempCur = *curAcPtr;
followNodePtr followingPtr = tempCur->followingPtr;
followNodePtr tempPtr;
followNodePtr tempPtr2;
tweetsNodePtr iterTwtPtr;
iterTwtPtr = *startTwtPtr;
*below here in question*
tempCur = *curAcPtr;
while (tempCur->followersPtr!=NULL){
acLoopPtr = *startPtr;
while (strcmp(acLoopPtr->username, tempCur->followersPtr->username)!=0){
acLoopPtr=acLoopPtr->nextPtr;
}
if (strcmp(acLoopPtr->followingPtr->username, tempCur->username)==0){
tempPtr=acLoopPtr->followingPtr->nextPtr;
free(acLoopPtr->followingPtr);
acLoopPtr->followingPtr=tempPtr;
}else{
tempPtr=acLoopPtr->followingPtr;
while(strcmp(tempPtr->nextPtr->username, tempCur->username)!=0){
tempPtr=tempPtr->nextPtr;
}
tempPtr2=tempPtr->nextPtr->nextPtr;
free(tempPtr->nextPtr);
tempPtr->nextPtr=tempPtr2;
}
tempPtr = tempCur->followersPtr->nextPtr;
free(tempCur->followersPtr);
tempCur->followersPtr=tempPtr;
}
This is the structure
typedef struct followsNode {
char username[MAX_USERNAME];
struct followsNode *nextPtr;
} followNode;
typedef struct accountsNode {
char username[MAX_USERNAME];
struct followsNode *followersPtr;
struct followsNode *followingPtr;
struct accountsNode *nextPtr;
} accountNode;
typedef followNode *followNodePtr;
typedef accountNode *accountNodePtr;

Attempting to lock a spinlock in the down function results in freezing

I am attempting to implement my own version of a semaphore into a linux vm and am running into a crash when I attempt to lock a spinlock inside the down function. Using GDB I found that the down is called immediately after the create function so the problem is definitely there.
Here is the create function:
asmlinkage long sys_create(int value, char name[32], char key[32]){
struct sem *new_sem = (struct sem*) kmalloc(sizeof(struct sem), GFP_ATOMIC);
struct sem_node *new_sem_node = (struct sem_node*) kmalloc(sizeof(struct sem_node), GFP_ATOMIC);
struct sem_node *curr_sem = sem_list_head;
new_sem_node->sem = new_sem;
spin_lock(&sem_lock);
new_sem->sem_id = IDcntr++;
spin_lock_init(&(new_sem->lock));
strncpy(new_sem->key, key, 32);
strncpy(new_sem->name, name, 32);
if(curr_sem == NULL)
{
sem_list_head = new_sem_node;
}
else
{
while(curr_sem->next != NULL)
{
curr_sem = curr_sem->next;
}
curr_sem->next = new_sem_node;
}
spin_unlock(&sem_lock);
return new_sem->sem_id;
}
Functions spin_lock, spin_unlock, and spin_lock_init are working as intended. The down function calls:
spin_lock(&(sem_list_head->sem->lock));
right at the beginning and freezes. To be more specific, in the gdb terminal, I try and get to the next line and it stops and in the actual machine it's completely stopped. No other functions are called between the create and down function. Below is the header file that defines the sem_node, process_node, and sem objects used in the create and down functions:
int IDcntr = 1;
DEFINE_SPINLOCK(sem_lock);
struct sem_node
{
struct sem* sem;
struct sem_node* next;
};
struct process_node
{
struct process_node* next;
struct task_struct* task;
};
struct sem
{
int value;
long sem_id;
spinlock_t lock;
char key[32];
char name[32];
struct process_node* head;
struct process_node* tail;
};
struct sem_node* sem_list_head = NULL;
Through independent testing the function DEFINE_SPINLOCK and object spinlock_t are working as intended. After thorough debugging the problem is in the create function. I freely admit that I am still learning how semaphores work so chances are I didn't set variables correctly or define things correctly. Any help in pointing me the right way would be greatly appreciated.

Destroying a double threaded binary tree

So we have been asked to implement double threaded binary tree. They give us the function declarations and structures involved and we're supposed to give the function definitions.
The structure of a node of binary tree:
typedef struct node
{
int data;
struct node *left;
struct node *right;
int rightThread;
int leftThread;
} Node;
The tree structure:
typedef struct tree
{
Node *root;
} Tree;
Now i don't know why they ask us to implement this using two structures (one for tree and one for node) but we cannot change these.
I have so far managed to insert nodes into the threaded tree, etc, etc but am having trouble with destroying the tree
We have been asked to implement it in the following way:
void tree_destroy(Tree *tree);
{
//TODO
}
void destroy(Node *r)
{
//TODO
}
I have implemented it as follows:
void destroy(Node *r)
{
if(r==NULL)
return;
{
destroy(r->left);
destroy(r->right);
}
free(r);
}
void tree_destroy(Tree *t)
{
if(t->root==NULL) return;
destroy(t->root);
free(t);
}
But there seems to be some problem with my code because there is a segmentation fault. Can someone please help me spot it OR have another way to implement the given functions?
EDIT:
The main function call:
Tree my_tree;
tree_initialize(&my_tree);
.
.
.
tree_destroy(&my_tree);
The function tree_initialize:
void tree_initialize(Tree *tree)
{
tree->root=NULL;
}
When i have to add a new node to the tree, i initialize it in the following way:
Node* newnode=(Node*)malloc(sizeof(Node));
newnode->data=data;
newnode->left=newnode->right=NULL;
newnode->rightThread=newnode->leftThread=1;
The free(t); in tree_destroy is the problem: tree_initialize doesn't allocates struct tree, so tree_destroy should not free it.
Prototypes of the function tree_initialize assumes and the code
Tree my_tree;
tree_initialize(&my_tree);
.
.
.
tree_destroy(&my_tree);
makes my_tree to be stack, not heap variable and it could not and should not be free'd.
However, there is an approach to make Tree structure to be heap variable. In this case tree_initialize should looks like
Tree *tree_initialize()
{
Tree tree = malloc (sizeof(tree));
if (!tree) return NULL;
tree->root=NULL;
return tree;
}
and your initial tree_destroy containing free for Tree would be proper solution, but main should calls them like this:
Tree *my_tree = tree_initialize();
if (!my_tree) /* ERROR */
.
.
.
tree_destroy(my_tree);
Please note the extra checks for malloc fails in Tree allocation in tree_initialize and main and absence of & in tree_destroy call as well as in other functions like tree_insert and tree_delete using Tree * as an argument..

Static allocation of struct members within another static struct?

I am trying to implement a low-level thread lock without the use of dynamic memory allocation; this code will basically be used on a completely bare-bones kernel.
However, I am running into the problem of receiving a seg fault when I am trying to dereference a member inside this global static struct. My code is as such
My wrapper struct
/** LOCKING STRUCT & FUNCTIONS **/
struct lock {
int free;
struct thread_list* wait_list;
struct thread* current_holder;
};
The nested struct(intended as a linked list sort of deal)
struct thread_list {
struct thread *head;
};
And the member inside this list
struct thread {
void *top; // top of the stack for this thread
void *sp; // current stack pointer for this thread (context)
void (*start_func)(void *);
void *arg;
int state;
int exit_value;
struct thread *join_thread;
struct thread *next_thread;
int id;
};
The method I'm trying to implement is as such
void lock_init (struct lock *lk) {
lk->free = 1; //Set lock as free
struct thread_list waiting = lk->wait_list; //Get waitlist, works fine
waiting->head = NULL; //Set waitlist's head to null, SEGFAULTS HERE
}
I am not super proficient at C, but I can't seem to figure out the correct methodology/syntax to make my code work like this.
struct thread_list waiting = lk->wait_list; //Get waitlist, works fine
waiting->head = NULL; //Set waitlist's head to null, SEGFAULTS HERE
waiting is not a struct pointer but a struct variable . To access member using it you need to use . operator -
waiting.head = NULL;
Or to use -> operator declare it as a struct pointer .

Resources