I am creating a simple graph with nodes and edges. I got the functionality going but got some memory bugs.
I have a typedef struct in header file:
typedef struct Graph_s* Graph;
And implementation in c. file:
struct Graph_s {
Node* nodeArray;
Edge* edgeArray;
size_t edges;
size_t nodes;
};
And function for construction:
Graph create_graph() {
Graph newGraph = malloc(sizeof(Graph));
newGraph->edges = 0;
newGraph->nodes = 0;
return newGraph;
}
The line Graph newGraph = malloc(sizeof(Graph)) gives: Invalid write of size 8 from Valgrind.
malloc(sizeof(Graph)) is only allocating enough memory for a pointer. Change it to malloc(sizeof(struct Graph_s)).
Related
I have the following Hash_table and Hash_bucket structs
typedef struct Hash_Table{
struct Bucket** bucket;
}Table;
typedef struct Bucket{
struct Bucket* next;
int num;
}Bucket;
I want to allocate 5 Hash Tables which i do like this,
Table** hash_tables = malloc(sizeof(Table*)* 5);
for(int i = 0; i <=4 ; i++){
hash_tables[i] = NULL;
}
To my knowledge, what I have done up to here is correct, and I want to proceed allocating the Hash Tables in my code. As i did with the double pointer above, my allocation for the Hash Table
hash_table[0] = malloc(sizeof(Table));
hash_table[0]->bucket = malloc(sizeof(Bucket*)*10); /* line 2 that is problematic*/
I allocate the size for a Hash_Table and then 10 Hash_Bucket pointers. However, I am having leaks and NOT because I free the memory wrongly. The line 2 of the allocation seems to be redundant (?) and if I replace the Hash_Table with
typedef struct Hash_Table{
struct Bucket* bucket[10];
}Table;
, then the line 2 is not needed, everything works perfect and memory is free'd. I really am clueless as to what I am doing wrong. I've found the mistake, but don't see the mistake in the first place. Thank you all.
The Code you posted without the "line 2 is redundant" part should look like this right:
typedef struct Bucket {
struct Bucket* next;
int num;
} Bucket;
typedef struct Hash_Table {
struct Bucket** bucket;
} Table;
int main(void)
{
// Create hashtable
Table** hash_tables = malloc(sizeof(Table*) * 5);
for (int i = 0; i <= 4; i++) {
hash_tables[i] = NULL;
}
// Create Bucket
hash_tables[0] = malloc(sizeof(Table));
hash_tables[0]->bucket = malloc(sizeof(Bucket*)*10); /* line 2 that is problematic*/
free(hash_tables[0]->bucket);
free(hash_tables[0]);
free(hash_tables);
return 0;
}
If you add the right free's at the bottom you shouldn't have memory leaks.
At least Valgrind says so.
Note: for every written malloc in your code, you need at least 1 free
I don't understand why I need double pointers inside 'struct graph'. Is it because it allows me to access one of the nodes that I made inside the function makeGraph()?
If I use one pointer (struct node *adjList) then I can't set the nodes to NULL that I made inside makeGraph().
I got the code frome programiz.com and in the article that explains this code it says: Don't let the struct node** adjList overwhelm you. All we are saying is we want to store a pointer to struct node*. This is because we don't know how many vertices the graph will have and so we cannot create an array of Linked Lists at compile time.
If I do: graph->adjList[1] does it go to the address of the second node or goes it inside the node? (I'm talking about the nodes that I create inside makeGraph())
I understand the rest of the code. If anyone can help me it would be appreciated.
#include <stdlib.h>
#include <stdio.h>
struct node
{
int vertex;
struct node *next;
};
struct graph
{
int numVertices;
struct node **adjList; // <--- THIS ONE
};
struct graph *makeGraph(int vertices) // Creating a Graph
{
struct graph *graph = malloc(sizeof(struct graph));
graph->numVertices = vertices;
graph->adjList = malloc(sizeof(struct node) * vertices); // creating the nodes
for (int i = 0; i < vertices; i++)
graph->adjList[i] = NULL; // Setting all nodes to NULL
return graph;
}
void addEdge(struct graph *graph, int src, int dest) // Add Edge
{
struct node *newNode = makeNode(dest);
newNode->next = graph->adjList[src];
graph->adjList[src] = newNode;
struct node *newNode2 = makeNode(src);
newNode2->next = graph->adjList[dest];
graph->adjList[dest] = newNode2;
return;
int main()
{
struct graph *graph1 = makeGraph(4);
addEdge(graph1, 0, 1);
addEdge(graph1, 0, 2);
addEdge(graph1, 0, 3);
}
An adjacency list is being represented as a linked list of struct node. The list is accessed by a pointer to the first element of the list. (The pointer will be NULL when the list is empty.) The pointer has type struct node *.
The graph has a number of vertices as set in the numVertices member of struct graph. Each vertex needs an adjacency list, and each adjacency list needs a struct node *. So the graph needs an array of struct node * of length numVertices. The authors of the code chose to allocate the array dynamically as a separate memory block pointed to by the adjList member. The type of the adjList member is a pointer to the element type. The element type is struct node * so the type of the adjList member is struct node **.
There is another way to allocate the memory for the struct graph and its adjacency list. They could be allocated as single block by changing the adjList member to be a flexible array member, as shown below:
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
struct node
{
int vertex;
struct node *next;
};
struct graph
{
int numVertices;
struct node *adjList[]; // <--- FLEXIBLE ARRAY MEMBER
};
struct graph *makeGraph(int vertices) // Creating a Graph
{
struct graph *graph = malloc(offsetof(struct graph, adjList[vertices]));
graph->numVertices = vertices;
for (int i = 0; i < vertices; i++)
graph->adjList[i] = NULL; // Setting all nodes to NULL
return graph;
}
offsetof(struct graph, adjList[vertices]) is the offset in bytes from the address of a struct graph to the address of the adjList[vertices] array member element. Allocating a block of memory of that size is just large enough to hold a struct graph plus the array of pointers. Another way to specify the size is sizeof(struct graph) + vertices * sizeof(struct node *) or alternatively sizeof(struct graph) + vertices * sizeof(graph->adjList[0]), but I think using the offsetof macro is a more succinct way to specify the size.
I know that . is used when there is a direct access to a variable in the structure and -> is used when you are accessing a variable of a structure through a pointer to that structure. Also a->b is equivalent to (*a).b
Here we are accessing the pointer variable head of structure AdjList through a pointer stored in graph->array[i] but still using . for access.
graph->array[i].head = *((*graph).array+i).head
graph->array[i]->head = (* *((*graph).array+i)).head
// A structure to represent an adjacency list node
struct AdjListNode
{
int dest;
struct AdjListNode* next;
};
// A structure to represent an adjacency list
struct AdjList
{
struct AdjListNode *head;
};
// A structure to represent a graph. A graph
struct Graph
{
int V;
struct AdjList* array;
};
// A utility function that creates a graph of V vertices
struct Graph* createGraph(int V)
{
struct Graph* graph =
(struct Graph*) malloc(sizeof(struct Graph));
graph->V = V;
// Create an array of adjacency lists. Size of
// array will be V
graph->array =
(struct AdjList*) malloc(V * sizeof(struct AdjList));
// Initialize each adjacency list as empty by
// making head as NULL
int i;
for (i = 0; i < V; ++i)
graph->array[i].head = NULL;
return graph;
}
But when we do tree traversal we do root->left->left = (*(*root).left).left then it works fine.
If anyone can help me understand this with memory diagram that would be a great help, I made this memory diagram for better understanding.
I'm trying to create a HashTable in C where each 'bucket' is a pointer to a LinkedList. That is, I need to create an array of LinkedList pointers.
As of now, SomeHashTable->Buckets[i] is returning a non-pointer LinkedList. I've been looking for answers everywhere and I just can't find anything. Perhaps I'm overlooking something? I've given my current code below.
HashTable.h
#include "LinkedList.h"
typedef struct HashTable
{
LinkedList* Buckets[1009];
} HashTable;
//Creates new hashtable
HashTable* HashTable_new();
//Hashes and adds a new entry
void HashTable_add(HashTable* Table, int data);
HashTable.c
#include "HashTable.h"
HashTable* HashTable_new()
{
HashTable* newTable = (HashTable*)malloc(sizeof(HashTable));
newTable->Buckets = malloc(1009 * sizeof(LinkedList*));
//Create linked lists
for (int i = 0; i < 1009; i++)
{
newTable->Buckets[i] = LinkedList_new();
}
return newTable;
}
void HashTable_add(HashTable* Table, int data)
{
int index = data % 1009;
//Get bucket to hash to
LinkedList* BucketHead = (Table->Buckets[index]);
//Hash it iiinnnn real good
LinkedList_add_at_end(BucketHead, data);
}
The linked List structs for reference:
typedef struct LinkedListNode {
int data;
struct LinkedListNode *next;
struct LinkedListNode *prev;
} LinkedListNode;
typedef struct LinkedList {
struct LinkedListNode *first;
struct LinkedListNode *last;
} LinkedList;
As H.S.'s comment mentions, there is no need to dynamically --and-- statically allocate the Buckets array.
This line:
newTable->Buckets = malloc(1009 * sizeof(LinkedList*));
is overwriting the pointer to the statically allocated array, which is probably not what you want. For scalability, I would ditch the static array and stick with malloc(). That way you could use an argument to HashTable_new() to specify the size of the buckets array, like so:
HashTable* HashTable_new(int nBuckets)
{
HashTable* newTable = (HashTable*)malloc(sizeof(HashTable));
newTable->Buckets = malloc(nBuckets * sizeof(LinkedList*));
newTable->nBuckets = nBuckets;
//Create linked lists
for (int i = 0; i < nBuckets; i++)
{
newTable->Buckets[i] = LinkedList_new();
}
return newTable;
}
Notice that newTable->Buckets is being allocated as a pointer to a pointer to LinkedList (LinkedList**). You'll need to keep track to the size of Buckets[], so add the variable to the struct as follows:
typedef struct HashTable
{
int nBuckets;
LinkedList **Buckets;
} HashTable;
You should be good as long as LinkedList_new()'s return type is LinkedList*, and don't forget to free() it all when you're done.
If I have several linked structures in C like:
struct structA {
int a;
int b;
struct structA *next;
}
struct structB {
char a;
int b;
struct structB *next;
}
and I dynamically allocate memory like this:
struct structA *mystructA = (struct structA*) malloc(sizeof(struct structA));
mystructA->next = (struct structA*) malloc(sizeof(struct structA));
struct structB *mystructB = (struct structB*) malloc(sizeof(struct structB));
mystructB->next = (struct structB*) malloc(sizeof(struct structB));
do I always have to free it for each struct type like this:
struct structA *p, *pNext;
for (p = mystructA; p != NULL; p = pNext) {
pNext = p->next;
free(p);
}
struct structB *p, *pNext;
for (p = mystructB; p != NULL; p = pNext) {
pNext = p->next;
free(p);
}
or is there any generic solution? I assume there is no other solution because the free() procedure must know how many bytes have to be freed. But maybe I'm wrong and someone can teach me better.
The standard way is to make the "list part" the first element of the structure, and let each derived struct share this same prefix. Since the first element is guaranteed to be placed at offset zero this wil work.
Example snippet:
#include <stdlib.h>
#include <string.h>
struct list {
struct list *next;
};
struct structA {
struct list list;
int a;
int b;
};
struct structB {
struct list list;
char a;
int b;
};
void *create_any(size_t size)
{
struct list *this;
this = malloc (size);
if (!this) return this;
memset(this, 0, size);
this->next = NULL;
return this;
}
void free_all_any(struct list **lp) {
struct list *tmp;
while ((tmp = *lp)) { *lp = tmp->next; free(tmp); }
}
#define CREATE_A() create_any(sizeof(struct structA))
#define CREATE_B() create_any(sizeof(struct structB))
#define FREE_A(pp) free_any((struct list **) pp)
#define FREE_B(pp) free_any((struct list **) pp)
int main(void)
{
struct structA *ap;
struct structB *bp;
ap = CREATE_A ();
bp = CREATE_B ();
// some code here ...
FREE_A( &ap);
FREE_B( &bp);
return 0;
}
This is more or less the method used in the linux kernel, but a lot more preprocessor magic is used there. (and there is no malloc there, obviously)
Since free() accepts pointers to void * and structA and structB both have the same size, you can pass both pointer types.
This is, however, not optimal in terms of elegance. You should think about the following questions:
Why do you have two different structs with the same members?
Why do you not have a generic list item type, such as the following:
struct list_node {
void *data;
struct list_node *next;
}
Actually, this is a very interesting question. The part is true that you have to free() each struct type individually, as they have been malloc()-ed individually, and each memory block has been allocated specifically for that type.Also, on some systems char and int have different storage sizes, but you can try a solution like Phillip provided. For more info, read about the doom memory engine. On a side note, please don't cast malloc() in C. The funny thing is that once the program is terminated, the operating system will reclaim the memory, so if you only deallocate the structures near the end of the program, when you don't need them anymore, it may not be necessary to free() them