typedef char *string;
struct node_t
{
struct node_t *prev;
string data;
struct node_t *next;
};
typedef struct node_t *node;
struct list_t{
struct node_t *head;
struct node_t *tail;
};
typedef struct list_t *list;
void list_destroy (list l){
node next = NULL;
if (l != NULL) {
node tmp = l->head;
while (tmp!=NULL) {
next = tmp->next;
free(tmp->data);
free(tmp);
tmp = next;
}
free(l);
}
};
I am trying to write function to free double linked list, when I am free char* type data, why it still have '\0' left? how can I free it completely?
Related
I'm trying to free a double linked list and my question is if I also need to free all the data and pointers in every node. Thank you.
Function:
static void free_list(Room *head, Room *head2) {
Room *tmp = head;
Room *tmp2 = head2;
Room *store;
Room *store2;
tmp = head2;
tmp2 = head;
printf("\nFreeing trap list...\n");
sleep(2);
while (tmp != NULL) {
store = tmp->pNext;
free(tmp);
tmp = store;
}
printf("\nFreeing rooms list...\n");
sleep(2);
while (tmp2 != NULL) {
store2 = tmp2->pNext;
free(tmp2);
tmp2 = store2;
}
}
Structure:
typedef struct Room {
struct Room *forward;
struct Room *left;
struct Room *right;
struct Room *previous;
struct Room *pPrev;
struct Room *pNext;
Room_Type Room_Type;
bool emergency_call;
} Room;
So do I also need to free, in the example, the forward pointer and also the other types as well? head and head2 are two different pointers, each points to the start of two different lists.
This way of defining the container is very confusing:
typedef struct Room{
struct Room* forward;
struct Room* left;
struct Room* right;
struct Room* previous;
struct Room* pPrev;
struct Room* pNext;
Room_Type Room_Type;
bool emergency_call;
} Room;
Divide and conquer:
typedef struct Node {
struct Node* pPrev;
struct Node* pNext;
Room_Type Room_Type;
bool emergency_call;
} Node;
typedef struct List {
struct Node* pHead;
struct Node* pTail;
} List;
With this approach, one loop is enough:
void free_list(List *list)
{
Node *node = list->pHead;
while (node != NULL)
{
Node *next = node->pNext;
free(node);
node = next;
}
free(list);
}
I am trying to add to a linked list generically, because i have 2 linked lists and I call the same function for the two lists.
void addToList(void* (*createNode)(void *data,char* name), int (compare)(void *a1, void *a2), void *(*getNext)(void), void(*setNext)(void *node, void* data), void *data,char* name, void **list) {
void *node = createNode(data,name);
void *head = *list;
if (head == NULL) { // if list is empty
*list = node;
}
else if (compare(head, node)) { // if first element is greater than node to add (meaning we need to add node to head of list)
setNext(node, list);
*list = node;
}
else {
// node will be inserted someplace other than head
void *current = head;
while (getNext(current) != NULL && compare(node, getNext(current))) {
// loop until we are at the end of the list OR until we have found an element greater than us
// basically, current will be the place to put the new node in
current = getNext(current);
}
setNext(node, getNext(current));
setNext(current, node);
}
Here is the struct and list and node
struct Stud {//my struct contains 2 lists
int id;
float gradeAverage;
float incomeAverage;
struct gradeList *gradelist;
struct incomeList *incomelist;
};
typedef struct Stud Students;
struct gradeNode {//the grade node with what is inside it
char courseName[20];
int grade;
struct gradeNode *next;
struct gradeNode *prev;
};
struct gradeList {//my first list with head and tail
struct gradeNode *head;
struct gradeNode *tail;
int size;
};
struct incomeNode {//my secound node
char *workplace;
float income;
struct incomeNode *next;
struct incomeNode *prev;
};
struct incomeList {//the secount list
struct incomeNode *head;
struct incomeNode *tail;
int size;
};
Here are the functions that I used
void* get_next_Income(void* head) {//used above in the generic call
return((struct incomeNode *)head)->next;
}
void* get_next_Grade(void* head) {//used above to get the income
return(((struct gradeNode *)head)->next);
}
int compareGradeNode(void *a1, void *a2) {//compares the node iam adding to the exicting node and adding accordingly
return ((struct gradeNode*)a1)->grade > ((struct gradeNode*)a2)->grade;
}
int compareIncomeNode(void *a1, void *a2) {
return ((struct incomeNode*)a1)->income>((struct incomeNode*)a2)-
>income;
}
void setNextGradeNode(void* node, void* data) {//seting the next graded
((struct gradeNode*)node)->next = data;
}
void setNextIncomeNode(void* node, void* data) {//setting the next income
((struct incomeNode*)node)->next = data;
}
Students students[30];
int numOfStuds = 0;
void* createGradeNode(void* data,char*name) {
struct gradeNode* nd=(struct GradeNode*)malloc(sizeof(struct gradeNode));
strcpy(nd->courseName, name);
assert(nd != NULL);
nd->grade = data;//setting the new node to the data the user entered!
nd->next = NULL;
return nd;//and return it
}
The problem is that I got a null ptr in the code part below.
I am using visual studio and can't solve it.
Please help.
Sorry for the long code, I am new to c.
void *head = *list;
if (head == NULL) { // if list is empty
*list = node;
I'm trying to compare a letter to data part in order to insert it in alphabetical order in linked list, What is wrong with this?
typedef struct{
char data;
struct list_node *next;
}list_node;
typedef struct{
list_node *head;
}list;
I'm trying to do the following:
void input_char(list *my_list, char x)
{
list_node *node = (list_node*)calloc(1, sizeof(list_node));
list_node *tmp = my_list->head;
node->data = x;
if (tmp == NULL)
my_list->head = tmp;
else if (tmp->next == NULL)
{
if (x < tmp->data)
{
node->next = tmp;
my_list->head = node;
}
else
tmp->next = node;
tmp = tmp->next;
}
else
{
if (x < tmp->next->data)
// This following line says "Error, Pointer to incomplete type is not allowed.
{
node->next = tmp->next;
tmp->next = node;
}
tmp = tmp->next;
}
}
Change
typedef struct{
char data;
struct list_node *next;
}list_node;
to
typedef struct list_node{
char data;
struct list_node *next;
}list_node;
Your compiler doesn't know what struct list_node is, so you have to declared it.
I'm supposed to write a function to remove the first node in a linked list.
List is defined like so:
struct ListNode{
int nInfo;
struct ListNode *next;
};
struct ListNode *createNode(int nInfo) {
ListNode *node;
node->nInfo = nInfo;
node->next = NULL;
return node;
}
void insertNode(struct ListNode **list, struct ListNode *node) {
//Sorting list after nInfo
struct ListNode *temp;
struct ListNode *tmpList = *list;
if(*list != NULL) { //List exists
while((tmpList->next != NULL)) {
if((tmpList->nInfo >= node->nInfo) && (tmpList->next->nInfo < node->nInfo)) {
break;
}
tmpList = tmpList->next;
}
//Found where to insert the node
temp = tmpList->next; //Saving old nextnode
tmpList->next = node; //Assigning new nextnode
node->next = temp; //Re-inserting old node
}
else{
*list = node;
}
}
The function for removing the first node looks like this:
void deleteFirst(struct ListNode **list) {
//Delete first node
struct ListNode *temppointer = *list;
if(temppointer == NULL)
return; //List is NULL
*list = temppointer->next;
}
I use the functions like so:
struct ListNode *list = createNode(100);
struct ListNode *node1 = createNode(50);
insertNode(list, node1); //Gives error, cannot convert ListNode* to ListNode**
deleteFirst(list); //Same error
I can't figure out how to obtain a pointer to the list pointer.
As we suspected, you forget to allocate memory for your nodes:
struct ListNode *createNode(int nInfo) {
ListNode *node;
node->nInfo = nInfo;
node->next = NULL;
return node;
}
Your *node is a pointer, but it still points to nothing. You must ask the heap for memory for your node:
ListNode *node = malloc(sizeof(ListNode));
Then in DeleteNode, you must return the memory to the heap, as you no longer need it:
void deleteFirst(struct ListNode **list) {
//Delete first node
struct ListNode *temppointer = *list;
if(temppointer == NULL)
return; //List is NULL
*list = temppointer->next;
free(temppointer); // release the memory.
}
Pay attention! The function you wrote for creating a node cannot work as it is: the node is allocated on the stack, in the context of the function, and it is invalid after the function has exited.
You have to allocate the memory for the node on the heap, using (p.e.) malloc. The function that remove the node from the list is responsable for its deallocation, usually using free.
[posting as an answer to get the formatting right]
Note: your insert() function is overly complex. It can be reduced to
void insertNode(struct ListNode **list, struct ListNode *node) {
for( ; *list ; list = &(*list)->next ) { //List exists
if(*(list)->nInfo >= node->nInfo) break;
}
//Found where to insert the node
node->next = *list;
*list = node;
}
#include <stdlib.h>
struct ListNode{
int nInfo;
struct ListNode *next;
};
struct ListNode *createNode(int nInfo) {
struct ListNode *node=malloc(sizeof(*node));
if(node){
node->nInfo = nInfo;
node->next = NULL;
}
return node;
}
void insertNode(struct ListNode **list, struct ListNode *node) {
// for safety
if(!list) return;
if(!node) return;
//Sorting list after nInfo
struct ListNode *temp;
struct ListNode *tmpList = *list;
if(tmpList!= NULL) { //List exists
while(tmpList->next) {
if(
((tmpList->nInfo)>= (node->nInfo))
&&
((tmpList->next->nInfo) < (node->nInfo))
) {
break;
}
tmpList = tmpList->next;
}
//Found where to insert the node
temp = tmpList->next; //Saving old nextnode
tmpList->next = node; //Assigning new nextnode
node->next = temp; //Re-inserting old node
}
else{
*list = node;
}
}
void deleteFirst(struct ListNode **plist) {
if(!plist) return;
struct ListNode *list=*plist;
if(!list) return;
*plist=list->next;
free(list);
return ;
}
void printNodes(char *title,struct ListNode *list){
printf("\n== %s\n",title);
while(list){
printf("\t%d\n",list->nInfo);
list=list->next;
}
printf("\n");
}
int main(){
struct ListNode *list = createNode(100);
struct ListNode *node1 = createNode(50);
insertNode(&list, node1);
printNodes("on start",list);
insertNode(&list, createNode(70));
printNodes("after add 70",list);
deleteFirst(&list);
printNodes("after del first",list);
}
I want to write a small function that shall free the memory of a linked list. The nodes have been created with malloc.
A typical function for this is:
void freeList(struct node* head)
{
struct node* tmp;
while (head != NULL)
{
tmp = head;
head = head->next;
free(tmp);
}
}
My problem is that I receive the following errors and i dont know how to fix them:
warning: assignment from incompatible pointer type tmp = l;
error: 'linked_list' has no member named 'next' l = l -> next;
The declarations are given:
struct node_s {
struct node_s *next;
char msg[MAX_MSG_LEN];
unsigned int time;
};
typedef struct node_s node;
struct linked_list_s {
node *head;
};
typedef struct linked_list_s linked_list;
void list_free(linked_list *l) {
struct node *tmp;
while (l !=NULL) {
tmp = l;
l = l -> next;
free(tmp);
}
}
You need to assign l->head to the tmp variable inside list_free() function and have another variable to store the next node while you free() tmp, like this
void list_free(linked_list *l)
{
struct node *tmp;
struct node *next;
if (l == NULL)
return;
tmp = l->head;
while (tmp != NULL)
{
next = tmp->next;
free(tmp);
tmp = next;
}
}