freeing an array of lists - c

I got a memory leak in my program, and I can't understand why. I got a 4 size array of linked lists, and valgrind says there is a memory leak.
Here is my struct:
struct node {
achievementMen100m player;
char* playerName;
Men100mAchievement playerAchiInRound;
char*currentRound;
struct node *head;
struct node *next;
} node, *Node;
Here is my allocation in the create function:
for(int i=0; i<4;i++){
OG->games->head->phases[i] = malloc(sizeof(struct node)); //VALGRIND SAYS MEMORY ALLOCATED HERE NOT FREED!//
OG->games->head->phases[i]->head=NULL;
OG->games->head->phases[i]->next=NULL;
OG->games->head->phases[i]->playerAchiInRound = 0;
}
Here is my free-list function:
void listDestroy(struct node * list) {
struct node * currentPlayer = list;
struct node * temp;
while (currentPlayer != NULL) {
temp = currentPlayer;
currentPlayer=currentPlayer->next;
free(temp->playerName);
free(temp);
}
list = NULL;
free(list);
}
And this is the free function of the ADT:
void olympicGamesDestroy(OlympicGames OG) {
if (OG == NULL) {
return;
}
if (OG->games == NULL) {
free(OG);
return;
}
if (OG->games->head == NULL) {
free(OG->games);
free(OG);
return;
}
for (int i=0; i<4;i++) {
listDestroy(OG->games->head->phases[i]->head);
}
free(OG->games->next);
free(OG->games->head);
free(OG->games);
free(OG);
}
update
here is my entire .h file
typedef struct men100 {
Men100mAchievement olympicMinimum;
Men100mAchievement olympicSkipPre;
char* roundNames[4];
struct node* phases[4];
} men100, *Men100;
typedef struct gameList {
int name;
men100* head;
struct gameList *next;
} gameList, *GameList;
typedef struct olympicGames {
GameList games;
int numOfGames;
} olympicGames, *OlympicGames;

Your void olympicGamesDestroy(OlympicGames OG) looks strange!
You are allocating at OG->games->head->phases[i].
So, where are you freeing them? You are only working on OG->games->head->phases[i]->head and not on OG->games->head->phases[i].
Show the actual OlympicGames data structure.
UPDATE:
I don't have much time to verify the whole code:
But you can try the following:
for(int i=0; i<4; i++)
{
listDestroy(OG->games->head->phases[i]->head);
free(OG->games->head->phases[i]); // you need this
}

Related

Freeing tree that is NOT binary in C

I'm trying to free a tree that is not binary. It includes dozens of leaves and paths.
Basicly it's a tree that starts with a root of a chess board position, and includes a lot of other positions.
The structs are the following:
typedef char chessPos[2];
typedef struct _treeNodeListCell treeNodeListCell;
typedef struct _treeNode
{
chessPos position;
treeNodeListCell* next_possible_positions;
} treeNode;
typedef struct _treeNodeListCell
{
treeNode* node;
struct _treeNodeListCell* next;
} treeNodeListCell;
typedef struct _pathTree
{
treeNode* root;
} pathTree;
Basicly I want to free a whole path tree. For example, the path tree looks the following:
So the root of path tree is the root with "C3" written in it.
(Ignore the parts with the blue "X" on them, it just means that these tree nodes aren't in the tree in my program)
This is the way I was trying to free the tree:
void freePathTree(pathTree* ptr)
{
freeTreeNode(ptr->root);
free(ptr);
}
void freeTreeNodeListCell(treeNodeListCell* tmp)
{
if (tmp->next != NULL)
{
freeTreeNodeListCell(tmp->next);
}
freeTreeNode(tmp->node);
free(tmp);
}
void freeTreeNode(treeNode* tmp)
{
if (tmp->next_possible_positions == NULL)
free(tmp);
else
{
freeTreeNodeListCell(tmp->next_possible_positions);
}
}
But as always, when trying to free memory, I receive dozens of warnings.
How can I free this huge tree without getting any errors? What is wrong with my program?
Big thanks in advance!
The existing freeTreeNode function has a memory leak:
void freeTreeNode(treeNode* tmp)
{
if (tmp->next_possible_positions == NULL)
free(tmp);
else
{
freeTreeNodeListCell(tmp->next_possible_positions);
// Memory leak here. `tmp` has not been freed.
}
}
Rather than repeating the call free(tmp), the function can be restructured as follows to be more like freeTreeNodeListCell:
void freeTreeNode(treeNode* tmp)
{
if (tmp->next_possible_positions != NULL)
{
freeTreeNodeListCell(tmp->next_possible_positions);
}
free(tmp);
}
The freeTreeNode and freeTreeNodeListCell functions are mutually recursive. freeTreeNode could be changed to an iterative function that subsumes freeTreeNodeListCell by "flattening" the tree into a list of treeNodes and a list of treeNodeListCells as it goes:
void freeTreeNode(treeNode* node)
{
treeNodeListCell *cell = NULL;
treeNodeListCell **endCell = NULL;
while (node || cell)
{
if (!cell)
{
endCell = &cell;
}
if (node)
{
*endCell = node->next_possible_positions;
while (*endCell)
{
endCell = &(*endCell)->next;
}
free(node);
node = NULL;
}
while (!node && cell)
{
treeNodeListCell *tmp = cell;
node = cell->node;
cell = cell->next;
free(tmp);
}
}
}
As a more profound change, the data structure could be simplified by merging treeNodeListCell into treeNode so that there are fewer types to worry about and to reduce the number of memory allocations required to hold the tree:
typedef struct _treeNode
{
chessPos position;
struct _treeNode *next_possible_positions;
struct _treeNode *node;
} treeNode;
That turns it into a sort of binary tree turned on its side, where next_possible_positions points across to the siblings, and node points down to the children.
That would make the freeTreeNode function simpler. Recursive version:
void freeTreeNode(treeNode *node)
{
if (node)
{
freeTreeNode(node->next_possible_positions);
freeTreeNode(node->node);
free(node);
}
}
Iterative version:
void freeTreeNode(treeNode *node)
{
treeNode **end = &node;
treeNode *tmp;
while (*end)
{
end = &(*end)->next_possible_positions;
}
while (node)
{
*end = node->node;
while (*end)
{
end = &(*end)->next_possible_positions;
}
tmp = node;
node = node->next_possible_positions;
free(tmp);
}
}

Segmentation fault accessing struct member

I've been learning C and am having problems using linked lists. When looping over a pointer to a linked list I run into segmentation faults and I'm not sure why.
Looking at similar questions the suggestion is to allocate the memory, but I find this answer confusing. Do you have to use heap memory for linked lists, and if so why?
Here is my code:
#include <stdio.h>
typedef struct Node {
char *name;
struct Node *next;
} Node;
typedef struct Thing {
Node *node;
} Thing;
Thing make_thing()
{
Thing t = {
.node = NULL
};
return t;
}
Thing * add_node(Thing *t, char *name)
{
Node node = {
.name = name,
.next = t->node
};
t->node = &node;
return t;
}
void print_nodes(Thing *t)
{
Node *n = t->node;
while(n != NULL) {
printf("Node: %s\n", n->name);
n = n->next;
}
}
int main()
{
printf("Start\n");
Thing t = make_thing();
add_node(&t, "one");
printf("First %s\n", t.node->name);
print_nodes(&t);
return 0;
}
You are using objects with automatic storage out of their scope:
Node node = {
.name = name,
.next = t->node
};
t->node = &node;
return t;
Here you leak the pointer &node, which is invalid (out of scope) after the return, to the caller and use it here:
printf("First %s\n", t.node->name);
You have to allocate memory by using malloc() for your Node structure.
Example:
Node *node = malloc(sizeof *node);
node->name = name;
node->next = t->node;
t->node = node;
return t;
You have to care about freeing the memory when it is no longer used to prevent memory leaks.

Insert node in a linkedlist

I'm new to C and I'm stuck with the insert function in a linked list. When I try printing the list. The result isn't what I expect. I know it has something to do with pointers but I just can't get my head around it. What am I doing wrong here?
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
typedef struct CELL_NODE CellNode;
struct CELL_NODE {
int row;
int column;
CellNode *next;
};
struct LinkedList {
CellNode *head;
};
typedef struct LinkedList LinkedList;
void printList(LinkedList *myList) {
CellNode *curr = (*myList).head;
if (curr != NULL) {
printf("(%d,%d)", (*curr).row, (*curr).column);
if ((*curr).next != NULL) {
curr = (*curr).next;
printf(" - (%d,%d)", (*curr).row, (*curr).column);
}
} else {
printf("The list is empty");
}
printf("\n");
}
void insert(LinkedList *myList, CellNode *node) {
CellNode *ref = (*myList).head;
if (ref == NULL) {
(*myList).head = node;
} else {
while ((*ref).next != NULL) {
ref = (*ref).next;
}
(*ref).next = node;
}
}
int main(int argc, char *argv[]) {
LinkedList myList = { NULL };
for (int k = 0; k < 2; k++) {
CellNode myNode = { 1, k, NULL };
insert(&myList, &myNode);
printList(&myList);
printf("\n");
}
return 1;
}
The result I get is:
(1,0)
(1,1) - (1,1)
I'm expecting:
(1,0)
(1,0) - (1,1)
You should first change every instance of (*x).y to x->y to make your code much more readable.
Then, look at this code:
int main(int argc, char *argv[])
{
LinkedList myList = {NULL};
for(int k = 0 ; k<2 ; k++) {
CellNode myNode = {1,k,NULL};
insert(&myList,&myNode);
printList(&myList);
printf("\n");
}
return 1;
}
You create myNode as a local variable inside the for loop. That means that each iteration of the loop gets a new instance of myNode, destroying the previous one. So you've connected myNode to your linked list through pointers, and then you let it get destroyed the next time through the for loop.
If you're going to let some piece of code stash a pointer to something, you must ensure that something remains valid until there is no longer any possibility of those pointers being dereferenced.
You need to make a decision -- what will own the objects that the linked list contains pointers to? When will that lifetime end? And when they end, what will destroy them?
You haven't done this. So you have objects whose lifetimes end too early.
With
CellNode myNode = {1,k,NULL};
insert(&myList,&myNode);
you are passing a pointer to a local variable. The life time of this variable is just as long as the respective iteration of the loop, i.e. in the second iteration, the object of the first iteration is out of scope. So you will access an object which's life time has already ended by the pointer you stored in your list. This yields undefined behaviour.
Use dynamically generated objects instead (and don't forget to free them later on):
CellNode *myNode = malloc(sizeof(CellNode));
myNode->row = ...
You repeatedly insert a node into the linked list from a local variable that immediately goes out of scope. The behavior is undefined, your program might fail in many unpredictable ways.
You should modify the code this way:
change the insert function to take the element data as arguments and allocate a new node with malloc().
make printList() print the full list, not just the first couple of cells.
change the clumsy (*pointer).member notation into the equivalent but more idiomatic pointer->member notation.
return 0 from main for successful operation.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
typedef struct CellNode CellNode;
struct CellNode {
int row;
int column;
CellNode *next;
};
typedef struct LinkedList LinkedList;
struct LinkedList {
CellNode *head;
};
void printList(LinkedList *myList) {
CellNode *curr = myList->head;
if (curr != NULL) {
printf("(%d,%d)", curr->row, curr->column);
while (curr->next != NULL) {
curr = curr->next;
printf(" - (%d,%d)", curr->row, curr->column);
}
} else {
printf("The list is empty");
}
printf("\n");
}
CellNode *insert(LinkedList *myList, int row, int column) {
CellNode *node = malloc(sizeof(*node));
CellNode *ref = myList->head;
if (node != NULL) {
if (ref == NULL) {
myList->head = node;
} else {
while (ref->next != NULL) {
ref = ref->next;
}
ref->next = node;
}
}
return node; // return node pointer to allow the caller to detect out of memory error
}
int main(int argc, char *argv[]) {
LinkedList myList = { NULL };
CellNode *node;
for (int k = 0; k < 2; k++) {
insert(&myList, 1, k);
printList(&myList);
printf("\n");
}
// free the nodes
while ((node = myList->head) != NULL) {
myList->head = node->next;
free(node);
}
return 0;
}

What is wrong with my array of linked lists implementation as all elements get over-written?

I'm trying to implement a hash table as an array of linked lists. Currently I'm trying to have a simple hash table where the key is the index of the array and value is a singly linked list for implementing chaining.
This is the code that I've written so far:
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int value;
struct Node *next;
};
struct Node *hashtable[7];
int empty(int index)
{
if(hashtable[index]==NULL)
return 0;
return 1;
}
void addNode(int frame,struct Node **iter)
{
if(*iter==NULL)
*iter=malloc(sizeof(struct Node));
else
{
while((*iter)->next != NULL)
(*iter)=(*iter)->next;
(*iter)->next=malloc(sizeof(struct Node));
(*iter)=(*iter)->next;
}
(*iter)->value=frame;
(*iter)->next=NULL;
}
void print()
{
int i;
struct Node **iter;
for(i=0;i<7;i++)
{
iter=&hashtable[i];
while(*iter !=NULL)
{
printf("%d%s%d\n",(*iter)->value,"--",i);
(*iter)=(*iter)->next;
}
}
}
int main()
{
int i=0,count=7;
for(i=0;i<7;i++)
hashtable[i]=NULL;
i=empty(1);
printf("%d",i);
do
{
printf("Enter no:\n");
scanf("%d",&i);
struct Node** temp;
temp=&hashtable[i-1%7];
addNode(rand(),temp);
count--;
print();
} while(count > 0);
return 0;
}
When I'm calling print, I can only see one element added to one particular index, which is the last element that was added, what am I doing wrong here?
void add_node(int frame,struct Node **iter)
{
/* find (pointer to) NULL pointer at end of chain */
for ( ; *iter; iter = &(*iter)->next ) {;}
*iter = malloc(sizeof **iter );
(*iter)->value = frame;
(*iter)->next = NULL;
}

creating a queue of pointers in c

i have a dynamic number of pointers all having the same size. i need to store all the addresses of my pointers in some place like a link List in order to fetch them later on.
my question is what structs should i use. is the following correct:
struct Node{
int *k;
Node*Next;
}
struct LS{
Node*first,*last;
void push(Node*n);
Node* GetFirst();
Node* GetLast();
}
the LS is the linked list that stores Nodes. and a Node is a struct that holds the address of my pointer and a pointer to the next Node.
am i using int *k to store the address of my pointer correctly? should i continue with this implementation or is there any easier way to do this?
this sample code may help you start...
#include <stdio.h>
struct Node{
int *k;
Node *Next;
}* Temp;
struct LS
{
Node *first,*last;
void push(Node *MyNode)
{
MyNode->Next=NULL;
if(empty())
{
first=MyNode;
last=MyNode;
}
else
{
last->Next = MyNode;
last=MyNode;
}
}
Node* front()
{
return first;
}
void pop()
{
free(first->k);
first=first->Next;
}
bool empty()
{
if(first==NULL) return true;
return false;
}
};
int N=10;
int main()
{
LS Q;Q.first=NULL;
for(int i=0;i<3;i++)
{
Node *NewNode= (Node*)malloc(sizeof(Node));
NewNode->k = (int*)malloc(sizeof(int)*N);
for(int k=0;k<N;k++) NewNode->k[k]=i;
Q.push(NewNode);
}
while(!Q.empty())
{
Temp=Q.front();
for(int i=0;i<N;i++) printf("%d ",Temp->k[i]);
printf("\n");
Q.pop();
}
return 1;
}
Yes, your Node struct is correct.
As to whether there is an easier way it depends. If there is a maximum number of pointers that you will need then an array of pointers would be easier. If you can do it in C++ then an STL vector (can use it like an array, but underneath the hood it can grow dynamically as needed) is easier. If you have to do it in C and it has to be dynamic, though, then no, there is not an easier way.
WDM.H (microsoft header) has a bunch of linked list stuff to look at ( http://msdn.microsoft.com/en-us/library/ff547799(VS.85).aspx ) , I've cut and pasted from that, and added a very simple example.
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY;
typedef struct _MY_THING
{
LIST_ENTRY ListEntry;
ULONG randomdata1;
ULONG randomdata2;
ULONG randomdata3;
ULONG randomdata4;
} MY_THING, *PMY_THING;
#define CONTAINING_RECORD(address, type, field) ((type *)( \
(PCHAR)(address) - \
(ULONG_PTR)(&((type *)0)->field)))
VOID
InsertHeadList(
IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry
)
{
PLIST_ENTRY Flink;
Flink = ListHead->Flink;
Entry->Flink = Flink;
Entry->Blink = ListHead;
Flink->Blink = Entry;
ListHead->Flink = Entry;
}
VOID
InitializeListHead(
IN PLIST_ENTRY ListHead
)
{
ListHead->Flink = ListHead->Blink = ListHead;
}
PLIST_ENTRY
RemoveHeadList(
IN PLIST_ENTRY ListHead
)
{
PLIST_ENTRY Flink;
PLIST_ENTRY Entry;
Entry = ListHead->Flink;
Flink = Entry->Flink;
ListHead->Flink = Flink;
Flink->Blink = ListHead;
return Entry;
}
void main()
{
LIST_ENTRY HeadOfMyList;
MY_THING Thing;
InitializeListHead(&Head);
// example of add thing to list.
InsertHeadList(&HeadOfMyList, &Thing.ListEntry);
// example of removing thing from the list
PLIST_ENTRY listEntry = RemoveHeadList(&HeadOfMyList);
PMY_THING pThing = (PMY_THING) CONTAINING_RECORD(listEntry, MY_THING, ListEntry);
}

Resources