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

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;

Related

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.

Segmentation fault- queue won't initialize

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

Add syscalls to linux kernel

I'm new in working with kernel.
I want to add a linked list to my kernel, and I try to fix it like this link : Linux Kernel Programming–Linked List
here is code's that I added to sys.c :
syscall defenition:
SYSCALL_DEFINE1(init_process_list,pid_t,ppid)
{
LIST_HEAD(processList);
struct scallNode* newNode;
newNode = kmalloc(sizeof(*newNode), GFP_KERNEL);
newNode->ID = ppid;
INIT_LIST_HEAD(&newNode -> list);
list_add_tail(&newNode -> list , &processList.list);
printk(KERN_INFO "INIT PROCESS UID: %u\n", ppid);
return 0;
}
and my struct for linked list:
struct scallNode{
int ID;
struct file_struct ffs;
struct task_struct ts;
struct list_head list;
};
struct scallNode processList;
and when I compile the kernel, I saw this error:
error: ‘struct list_head’ has no member named ‘list’ list_add_tail(&newNode -> list , &processList.list);
thanks for your replies.
that error disappeared, but another one is still exist.
kernel/sys.c:2136:24: error: field ‘fs’ has incomplete type struct file_struct fs;
again thanks for your replies.
The list_add_tail function is
void list_add_tail(struct list_head *new, struct list_head *head);
The second param should a pointer to a struct list_head so just use like this:
list_add_tail(&newNode -> list , &processList);
I never did any kernel programming. But as per my knowledge below memory allocation is not correct:-
newNode = kmalloc(sizeof(*newNode), GFP_KERNEL);
I think it should be like:-
newNode = (struct scallNode *)kmalloc(sizeof(struct scallNode), GFP_KERNEL);
finally answer finded.
in list_add_tail(&newNode -> list , &processList.list);
, &processList most be use instead of &processList.list .
list_add_tail find list of processList itself.

How to make a link : chained list and pointer in c

Helle everyone, I'm stuck in a problem for 1 week and I come here..
I have few structures:
typedef struct s_task{
unsigned int id;
char *name;
}task
typedef struct s_element_task{
task *t;
struct s_element_task *next_element;
} element_task;
typedef element_task* task_list;
typedef struct s_agenda{
task_list *task_by_date;
} agenda;
I want to add a task to an agenda but I don't know how to make the link betewwen theses structures..
I start with:
task* my_task = malloc(sizeof(task));
but that's all..
thank you un advance
task* my_task = malloc(sizeof(task)); // data object
element_task* my_node = malloc(sizeof(element_task)); // node object
my_node.t = my_stask; // node now knows where data is
element_task* next_node = malloc(sizeof(element_task)); // next node object
my_node.next_element = next_node; // "link" to next node in linked list
As a side note, I'd make sure to initialize element_task.next_element to NULL so you can tell whether that node HAS a child or not.

C Casting between different struct-pointers during "simulated inheritance"

Hey I'm currently porting a C++ program into C and I simplified I'm using the following code when I'm simulating inheritence from C++ classes using structs in C.
typedef struct GenTask GenTask;
typedef struct Task Task;
typedef struct UserTask UserTask;
struct GenTask{
char name[MAXCHAR];
boolean isUserTask;
int k;
void (*print)(Task*);
};
GenTask* newGenTask(const char* n){
GenTask* inhTask = (GenTask*)malloc(sizeof(GenTask));
strncpy(inhTask->name, n, MAXCHAR);
inhTask->k = 1;
return inhTask;
}
struct Task{
GenTask* inhTask;
};
void printTask(Task* task){
printf("\nThis is Task: %s",task->inhTask->name);
}
Task* newTask(const char* n){
Task* task = (Task*)malloc(sizeof(Task));
task->inhTask = newGenTask(n);
task->inhTask->isUserTask = false;
task->inhTask->print = printTask;
return task;
}
void deleteTask(Task* task){
free(task->inhTask);
free(task);
}
struct UserTask{
GenTask* inhTask;
int m;
};
void printUserTask(Task* task){
UserTask* ut = (UserTask*)task;
printf("\nThis is UserTask nbr: %d",ut->m);
}
UserTask* newUserTask(const char* n){
UserTask *ut = (UserTask*)malloc(sizeof(UserTask));
ut->inhTask = newGenTask(n);
ut->inhTask->isUserTask = true;
ut->inhTask->print = printUserTask;
ut->m=100;
return ut;
}
void deleteUserTask(UserTask* utask){
free(utask->inhTask);
free(utask);
}
I've tried running the code and it works as expected (or rather as I wish for it to work;)). My question though, is if there is any risk that the extra "UserTask-memory" is exposed after type casting like below.
Task* task = (Task*)newUserTask("A UserTask");
There seems to be no problem when I cast back into a UserTask pointer.
UserTask* utask = (UserTask*)task;
I assume that when I free the memory for "A UserTask", I suffies to free utask and using deleteUserTask(utask)? If I instead free task using deleteTask(task), I guess the UserTask specific memory won't get freed.
I my all new to both C++ and C, been using Java before and the dynamic memory allocation is still a bit scary... Thanks for any help!
/Patrik
I think the 'normal' way to do this in C is to include the parent struct inline not as a pointer, i.e.:
struct Task{
GenTask inhTask;
};
That way a pointer to a task struct can be up cast to a Task*. And of course the 'parent' is freed automatically along with the child instance.

Resources