Memory Leak : Possible memory while scan through valgrind - c

I saw some random behavior while scanning my code through Valgrind. i have freed all possible memory blocks still I seeing Valgrind say 1 block is not properly freed.
Objective: Creating the 3 level json by using cJSON.c then in the second block modified the json format.
#include<stdio.h>
#include<stdlib.h>
#include"cJSON.h"
int main () {
cJSON *root = NULL, *root1 = NULL , *arrays = NULL, *array = NULL;
root = cJSON_CreateObject();
root1 = cJSON_CreateObject();
arrays = cJSON_CreateArray();
cJSON_AddItemToObject(root,"check",root1);
cJSON_AddItemToObject(root1, "innercheck",cJSON_CreateString("just to check"));
cJSON_AddItemToObject(root1, "array", arrays);
cJSON_AddItemToArray(arrays, array = cJSON_CreateObject());
cJSON_AddItemToObject(array, "innnerarray", cJSON_CreateNumber(1));
char *out = NULL;
printf("===================================================\n");
out = cJSON_Print(root);
printf("%s\n", out);
/* further operation now going to extract the value from json and readd new key */
cJSON *json_param = NULL, *exe1 = NULL , *exe2 = NULL;
json_param = cJSON_Parse(out);
exe1 = cJSON_GetObjectItem(json_param , "check");
cJSON_DeleteItemFromObject(exe1, "check");
exe2 = cJSON_CreateObject();
cJSON_AddItemToObject(exe2, "test", exe1);
char *out2 = NULL;
out2 = cJSON_Print(exe2);
printf("====================================================\n");
printf("%s\n", out2);
if(root) {
cJSON_Delete(root);
root = NULL;
}
if(json_param) {
cJSON_Delete(json_param);
json_param = NULL;
}
if(out) {
free(out);
out = NULL;
}
if(out2) {
free(out2);
out2 = NULL;
}
return 0;
}
Valgrind scan report :
==23708== Memcheck, a memory error detector
==23708== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==23708== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==23708== Command: ./object
==23708==
===================================================
{
"check": {
"innercheck": "just to check",
"array": [{
"innnerarray": 1
}]
}
}
====================================================
{
"test": {
"innercheck": "just to check",
"array": [{
"innnerarray": 1
}]
}
}
==23708==
==23708== HEAP SUMMARY:
==23708== in use at exit: 64 bytes in 1 blocks
==23708==
> total heap usage: 29 allocs, 28 frees, 2,661 bytes allocated
==23708==
==23708== 64 bytes in 1 blocks are definitely lost in loss record 1 of 1
==23708== at 0x4C2FDFB: malloc (vg_replace_malloc.c:309)
==23708== by 0x108F47: cJSON_New_Item (cJSON.c:214)
==23708== by 0x10C9F8: cJSON_CreateObject (cJSON.c:2410)
==23708==
> by 0x108BFA: main (object.c:35)
==23708==
==23708== LEAK SUMMARY:
==23708== definitely lost: 64 bytes in 1 blocks
==23708== indirectly lost: 0 bytes in 0 blocks
==23708== possibly lost: 0 bytes in 0 blocks
==23708== still reachable: 0 bytes in 0 blocks
==23708== suppressed: 0 bytes in 0 blocks
==23708==
==23708== For lists of detected and suppressed errors, rerun with: -s
==23708== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
I have freed all the possible memory block but unable to get why still I am getting 1 block is not properly free.

It seems there are two problems in your code.
Firstly, you need to release the exe2 object (which you had allocated using cJSON_CreateObject()) before exiting.
cJSON_Delete(exe2);
Secondly ... You need to detach the check object from json_param before adding it to the exe2 object. Otherwise you will have a double free when you call cJSON_Delete(exe2) - the library will attempt to free the same object twice (since the same object will have been attached as a child to more than one object).
So change
exe1 = cJSON_GetObjectItem(json_param, "check");
cJSON_DeleteItemFromObject(exe1, "check");
to simply
exe1 = cJSON_DetachItemFromObject(json_param, "check");
Note that I removed the line cJSON_DeleteItemFromObject(exe1, "check"); - as it is redundant as far as I can tell (unless you meant to remove the innercheck element instead).

Related

Valgrind errors for using free() in a linked list

I am making a project using a hash array. I am putting an image i found online to show you guys what i'm trying to do. image
So I've initialized the big array on the left like this in main:
cellule_t * array[HASH_MAX] = {NULL};
Then i have made all the insertions to create the linked lists. What i want to do now, is to free() all the memory allocated to create all this. So, like I'm not using malloc for the big array, i just need to free the linked lists and I'm using this function :
But i get some errors from Valgrind and the blocks are not freed.
I'm putting all the functions I use including the main to make it more clear.
typedef struct cell{
char *mot;
char *traduction;
struct cell *suivant;
}cellule_t;
int main()
{
int indice;
cellule_t *cel;
FILE*file = NULL;
char buffer[100] = "hello bye glass sorry";
cellule_t *tabMajeur[HASH_MAX] = {0};
file = fopen("fichier.txt","r");
remplissage_hachage(tabMajeur,file); (c:157)
affichageTraduction(tabMajeur,buffer);
libererMemorie(tabMajeur); (c:159)
}
void remplissage_hachage (cellule_t **tabMajeur,FILE *fichier)
{
char string1[20];
unsigned int indice = 0;
cellule_t *copy;
int boolean = 0;
char *string2, *string3 = NULL;
cellule_t *c =NULL;
while(fgets(string1,100,fichier) != NULL)
{
string2 = strtok(string1,";");
string3 = strtok(NULL,";");
string3[strlen(string3)-1] = '\0';
printf("string2 %s\n",string2);
printf("string3 %s\n",string3);
indice = hash_string(string2);
boolean = 0;
indice = recherche(tabMajeur,string2,&boolean,&c);
if(boolean != 1)
{
copy = tabMajeur[indice];
tabMajeur[indice] = creationCellule(string2,string3); (c: 64)
tabMajeur[indice]->suivant = copy;
}
}
}
cellule_t* creationCellule(char * mot, char *traduction)
{
cellule_t *nouveau = (cellule_t *) malloc(sizeof(cellule_t)); (c:24)
if(nouveau != NULL)
{
nouveau -> mot = strdup(mot);
nouveau -> traduction = strdup(traduction);
nouveau -> suivant = NULL;
}
return nouveau;
}
void libererMemorie(cellule_t **tabMajeur)
{
int i = 0;
cellule_t * cour;
cellule_t * copy;
for(i = 0 ; i < HASH_MAX; i++)
{
cour = tabMajeur[i];
while(cour != NULL)
{
copy = cour;
free(copy); (c:137)
cour = cour->suivant; (c:138)
}
}
}
The valgrind error is:
enter image description here
The text for valgrind error is:
==2550== Memcheck, a memory error detector
==2550== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2550== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==2550== Command: ./tp4
==2550==
string2 hello
string3 bonjour
string2 bye
string3 au revoir
string2 sorry
string3 pardon
string2 glass
string3 verre
La traduction est bonjour au revoir verre pardon
==2550== Invalid read of size 8
==2550== at 0x108E55: libererMemorie (tp4.c:138)
==2550== by 0x108F85: main (tp4.c:159)
==2550== Address 0x522ea40 is 16 bytes inside a block of size 24 free'd
==2550== at 0x4C30D3B: free (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2550== by 0x108E50: libererMemorie (tp4.c:137)
==2550== by 0x108F85: main (tp4.c:159)
==2550== Block was alloc'd at
==2550== at 0x4C2FB0F: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2550== by 0x108A5D: creationCellule (tp4.c:24)
==2550== by 0x108BD8: remplissage_hachage (tp4.c:64)
==2550== by 0x108F60: main (tp4.c:157)
==2550==
==2550==
==2550== HEAP SUMMARY:
==2550== in use at exit: 605 bytes in 9 blocks
==2550== total heap usage: 15 allocs, 6 frees, 5,821 bytes allocated
==2550==
==2550== LEAK SUMMARY:
==2550== definitely lost: 53 bytes in 8 blocks
==2550== indirectly lost: 0 bytes in 0 blocks
==2550== possibly lost: 0 bytes in 0 blocks
==2550== still reachable: 552 bytes in 1 blocks
==2550== suppressed: 0 bytes in 0 blocks
==2550== Rerun with --leak-check=full to see details of leaked memory
==2550==
==2550== For counts of detected and suppressed errors, rerun with: -v
==2550== ERROR SUMMARY: 4 errors from 1 contexts (suppressed: 0 from 0)
Can you please help me find out what's wrong?
The "Invalid Read" error may stem from the fact that while you have a singly-linked list for each bucket in your hash table, you are attempting to free the list node and then access the pointer to the next node after you've free'd the current node.
So basically here:
copy = cour;
free(copy);
cour = cour->suivant;
You are creating undefined behavior because you are freeing the node, then attempting to access the free'd memory via the cour pointer to get at the next pointer in the linked list. Assigning copy the value of cour only copied the pointer value itself. You then free'd the memory pointed to by both copy and cour, and then attempted to access the memory in a free'd block. Valgrind definitely won't like that.
You can simply change your ordering to the following:
copy = cour;
cour = cour->suivant;
free(copy);
Now you free the memory in the current node after copying out the pointer to the next node while the memory block is still a valid allocated memory block.

C memory leak that i can't find at all

So everything is fine with the program but i get a very annoying memory leak. I am sitting in front of my computer for couple hours and can figure it out.
We have 2 struck very simple, one struct is a double linked list and one is a hash table that stores that double linked list.
Now i am inserting a key and a data into the double linked list here is the function.
void htable_insert(htable* ht, int key, int data) {
// TODO: Insert a new entry with the given key and data
// Overwrite the old data if the key already exists, duplicate keys are not allowed
ht_entry *new_node;
ht_entry *head;
ht_entry *it;
int sameKey;
int bucketPosition;
new_node = (ht_entry*)malloc(1*sizeof(ht_entry));
bucketPosition = key % ht->size;
sameKey = 0;
for(it = ht->entries[bucketPosition]; it != NULL; it = it->next)
{
if(it->key == key) {
it->data = data;
sameKey = 1;
free(new_node);
new_node = NULL;
break;
}
}
if(!sameKey && new_node) {
head = ht->entries[bucketPosition];
if (head == NULL) {
new_node->key = key;
new_node->data = data;
new_node->next = head;
new_node->prev = NULL;
ht->entries[bucketPosition] = new_node;
new_node = NULL;
} else {
new_node->key = key;
new_node->data = data;
new_node->next = head;
// new_node->prev = head;
head->prev = new_node;
head = new_node;
ht->entries[bucketPosition] = head;
}
}
// free(new_node);
new_node = NULL;
printf("%s\n %d", "INSERT:", key);
for(it = ht->entries[bucketPosition]; it != NULL; it = it->next){
printf("it->key: %d\nit->data: %d\n", it->key, it->data);
}
printf("%s\n", "-------------------------------");
}
Here is my valgrind message:
==10692== Memcheck, a memory error detector
==10692== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==10692== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==10692== Command: ./chain_hash_table.out
==10692==
==10692==
==10692== HEAP SUMMARY:
==10692== in use at exit: 72 bytes in 3 blocks
==10692== total heap usage: 10 allocs, 7 frees, 376 bytes allocated
==10692==
==10692== 24 bytes in 1 blocks are definitely lost in loss record 2 of 3
==10692== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10692== by 0x4007EE: htable_insert (htable.c:53)
==10692== by 0x400BD2: main (main.c:14)
==10692==
==10692== 48 (24 direct, 24 indirect) bytes in 1 blocks are definitely lost in loss record 3 of 3
==10692== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10692== by 0x4007EE: htable_insert (htable.c:53)
==10692== by 0x400C25: main (main.c:18)
==10692==
==10692== LEAK SUMMARY:
==10692== definitely lost: 48 bytes in 2 blocks
==10692== indirectly lost: 24 bytes in 1 blocks
==10692== possibly lost: 0 bytes in 0 blocks
==10692== still reachable: 0 bytes in 0 blocks
==10692== suppressed: 0 bytes in 0 blocks
==10692==
==10692== For counts of detected and suppressed errors, rerun with: -v
==10692== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
And what i know it is always for first table insertion that is why it says at line main(18) for the rest after the first insertion there is no leaks.
Thank you guys for your time and help :)
Check the break statement in the loop, it breaks on the first iteration
and it does not deallocate the node.
The break should be placed inside the for loop.
If you are mallocing space in a C program, unless you free everything at the end, you will end up with memory leaks.
For your current program, I'm assuming that you don't free correctly in the end. So the problem isn't within the htable_insert function, but rather within your freeing/cleanup functions.
If you free your linked list nodes in your htable_insert, you will not be able to access them in the rest of your program and you'll run into segfaults.

Valgrind definitely lost block of memory

I am trying to figure out what is wrong with my valgrind debugging. I am starting to learn valgrind and there are some things I do not know how to solve
==12902== HEAP SUMMARY:
==12902== in use at exit: 40 bytes in 4 blocks
==12902== total heap usage: 21 allocs, 17 frees, 2,400,792 bytes allocated
==12902==
==12902== Searching for pointers to 4 not-freed blocks
==12902== Checked 77,768 bytes
==12902==
==12902== 40 (16 direct, 24 indirect) bytes in 2 blocks are definitely lost in loss record 2 of 2
==12902== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12902== by 0x400EAB: elequeue_ini (elequeue_point.c:15)
==12902== by 0x400F90: elequeue_copy (elequeue_point.c:67)
==12902== by 0x4012EC: queue_insert (queue.c:105)
==12902== by 0x400C24: main (p3_e1.c:85)
==12902==
==12902== LEAK SUMMARY:
==12902== definitely lost: 16 bytes in 2 blocks
==12902== indirectly lost: 24 bytes in 2 blocks
==12902== possibly lost: 0 bytes in 0 blocks
==12902== still reachable: 0 bytes in 0 blocks
==12902== suppressed: 0 bytes in 0 blocks
==12902==
==12902== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==12902== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Elequeue makes reference to the elements of a queue ADT. The codes involved are:
struct _EleQueue{
Point *info;
};
EleQueue* elequeue_copy(const EleQueue * src){
EleQueue *copied_ele;
if(src==NULL){
return NULL;
}
copied_ele=elequeue_ini();
if(copied_ele==NULL){
return NULL;
}
copied_ele->info=point_copy(src->info);
return copied_ele;
}
EleQueue* elequeue_ini(){
EleQueue *e;
e=(EleQueue*)malloc(sizeof(EleQueue));
if (e==NULL){
return NULL;
}
e->info=NULL;
return e;
}
Queue* queue_insert(Queue *q, const EleQueue* pElem){
EleQueue *auxElem;
if(!q || !pElem || queue_isFull(q) == TRUE){
return NULL;
}
auxElem=elequeue_copy(pElem);
if(auxElem == NULL){
return NULL;
}
*(q->end) = auxElem;
if(q->end == &(q->item[MAXQUEUE-1])){
q->end = &(q->item[0]);
} else {
q -> end++;
}
return q;
}

Valgrind detects reachable leaks, where are they?

I have written a small implementation of a simple stack in C using a linked list. The application works after a bit of fussing with gdb and valgrind. However, I have noticed that valgrind reports a number of "still reachable" leaks at termination of the program.
After some googling, I have found that these type of leaks are not an issue and that I generally shouldn't worry about them. Well that's great news! The only thing is, I would REALLY like to understand why valgrind sees these leaks and where they appear. I went to great pains through my first pass at this application to diligently release any allocated memory. What did I miss? Where are these allocations that valgrind sees but I cannot?
I have been staring at this for awhile now, and despite fiddling with the code this way and that, have come up empty handed. Hopefully you all can help me in this endeavor.
I have stripped the app down to a minimal example that will present the leak I am observing. It just initializes the stack and then immediately destroys it and exits.
// simple stack implementation
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
/*--- data structure in a stack item ---*/
struct data {
char * message;
};
/*--- stack item structure ---*/
struct item {
struct data * my_data;
struct item * next;
};
/*--- stack data structure ---*/
struct stack {
int initialized;
int empty;
struct item * head;
};
struct stack * my_stack;
/*--- create a new stack data structure with provided initial data ---*/
int
create_stack(struct data ** initial_items, int num_items) {
//allocate memory for the stack structure itself
my_stack = (struct stack *) malloc(sizeof(struct stack));
if(!my_stack) return -1;
my_stack->empty = 1;
my_stack ->initialized = 0;
if(num_items) {
//allocate memory for the head of the list first
my_stack->head = (struct item *) malloc(sizeof(struct item));
if(!my_stack->head) return -1;
my_stack->head->my_data = initial_items[0];
my_stack->head->next = NULL;
struct item * tracker = my_stack->head;
//fill the stack with elements containing the provided data
int i = 1;
for(; i < (num_items); i++) {
tracker->next = (struct item *) malloc(sizeof(struct item));
tracker = tracker->next;
if(!tracker) return -1;
tracker->my_data = initial_items[i];
tracker->next = NULL;
}
//no longer empty
my_stack->empty = 0;
}
//set initialized flag & return
my_stack->initialized = 1;
return 0;
}
/*--- destroy the stack by recursively freeing nodes ---*/
int
destroy_stack(struct item * recurse) {
//if the starting node is valid, begin
if(recurse) {
//if the current node links to another
if(recurse->next)
//recurse on the next node
destroy_stack(recurse->next);
else
//otherwise we hit the end, free the node
free(recurse);
}
//the starting node is invalid, just free the stack itself
else {
free(my_stack);
}
return 0;
}
/*--- test wrapper ---*/
int
main(int argc, char **argv) {
//initialize 10 element list of data structures to fill the stack items with
int i = 0;
int length = 10;
struct data ** initial_values = (struct data **) malloc(length*sizeof(struct data *));
//set each data element's value to i
for(; i < length; i++) {
char temp[16];
sprintf(temp, "%d", i);
initial_values[i] = (struct data *) malloc(sizeof(struct data));
initial_values[i]->message = strdup(temp);
}
//simple test case
//create a stack with the generated initial data, then destroy it
assert( !create_stack(initial_values, length) );
assert( !destroy_stack(my_stack->head) );
//free the string data our stack nodes were pointing to
i = 0;
while(i < length) {
free(initial_values[i]->message);
free(initial_values[i]);
i += 1;
}
free(initial_values);
return 0;
}
Running this through valgrind produces the following identified, unreleased blocks:
(trusty)kin3tix#localhost:~/C Practice/Data Structures$ valgrind --leak-check=full --show-leak-kinds=all ./stack_leak_test
==19340== Memcheck, a memory error detector
==19340== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==19340== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==19340== Command: ./stack_leak_test
==19340==
==19340==
==19340== HEAP SUMMARY:
==19340== in use at exit: 168 bytes in 10 blocks
==19340== total heap usage: 32 allocs, 22 frees, 364 bytes allocated
==19340==
==19340== 16 bytes in 1 blocks are still reachable in loss record 1 of 3
==19340== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19340== by 0x400739: create_stack (stack_leak_test.c:40)
==19340== by 0x40093B: main (stack_leak_test.c:95)
==19340==
==19340== 24 bytes in 1 blocks are still reachable in loss record 2 of 3
==19340== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19340== by 0x4006E6: create_stack (stack_leak_test.c:33)
==19340== by 0x40093B: main (stack_leak_test.c:95)
==19340==
==19340== 128 bytes in 8 blocks are still reachable in loss record 3 of 3
==19340== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19340== by 0x4007A1: create_stack (stack_leak_test.c:48)
==19340== by 0x40093B: main (stack_leak_test.c:95)
==19340==
==19340== LEAK SUMMARY:
==19340== definitely lost: 0 bytes in 0 blocks
==19340== indirectly lost: 0 bytes in 0 blocks
==19340== possibly lost: 0 bytes in 0 blocks
==19340== still reachable: 168 bytes in 10 blocks
==19340== suppressed: 0 bytes in 0 blocks
==19340==
==19340== For counts of detected and suppressed errors, rerun with: -v
==19340== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
They all seem to stem from "create_stack" but as far as I can tell my destroy function should be catching everything I allocate. What am I missing here?
Your destruction logic is trying to recursively combine two tasks (deleting the stack object and its items) in a single function. Worse, the else state shouldn't be there at all. You already determined you're sitting on a dynamic node (recurse). It needs to be deleted. Whether it has a next or not is not for the current depth to decide; that will be taken care of in the next depth of recursion.
Honestly, this is much simpler if you create a helper to wipe out the linked list, and as separate wrapper to do said-same to the stack itself:
/*--- destroy linked list nodes recursively ---*/
static void destroy_stack_items(struct item *item)
{
if (item)
{
destroy_stack_items(item->next);
free(item);
}
}
/*--- destroy the stack by recursively freeing nodes ---*/
int destroy_stack(struct stack *s)
{
if (s)
{
destroy_stack_items(s->head);
free(s);
}
return 0
}
and simply invoked as:
destroy_stack(my_stack);
Personally I would do it iteratively (thus remove the helper in the process), but I'm sure you have your reasons for otherwise. For example:
/*--- destroy the stack by iteratively freeing nodes ---*/
int destroy_stack(struct stack *s)
{
if (s)
{
while (s->head)
{
struct item *tmp = s->head;
s->head = tmp->next;
free(tmp);
}
free(s);
}
return 0
}
Best of luck.

Linked list :: hash table :: Valgrind error :: Conditional jump or move depends on uninitialised value

Need help again.
I've got my linked list working. It copies a list of words from a file into a linked list.
Now I want to make a hash table so that all words starting with the letter 'A' go into a bucket [0] of linked list.
The code I've written; it seems to work for small and large lists but Valgrind shows points to errors.
-----CODE-----
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct node //struct for linked list
{
char* word;
struct node* next;
}
node;
int findhash(char firstletter) //this function returns a hash value for first alphabet of every word
{
int hash = 0;
if(isupper(firstletter))
hash = firstletter-'A';
else hash = firstletter-'a';
return hash;
}
int main (void)
{
char* dictfile = "small";
FILE* dict = fopen(dictfile, "r");
if (dict == NULL)
return 1;
char oneword[47]; //to store the word from fscanf()
node* hashtable [30]; //creates a hashtable
for (int i = 0; i < 30; i++) //gives an index to every element in the hash table
{
node* temp = (node*)malloc(sizeof(node));
temp->next = NULL;
hashtable[i] = temp;
}
while ((fscanf (dict, "%s", oneword)) > 0)
{
node* temp = (node*)malloc(sizeof(node));
char* tempword = (char*)malloc(strlen(oneword)+1); //gives me a new pointer to store the string (as pointed out by Antione)
strcpy(tempword, oneword);
char firstletter = tempword[0];
int hash = 0;
hash = findhash(firstletter); //returns an index for the first alphabet of the word
temp->word = tempword;
//printf("%s\n", temp->word); //prints the value (just for debug)
temp->next = hashtable[hash];
hashtable[hash] = temp;
}
for (int i = 0; i < 30; i++)
{
node* temp = (node*)malloc(sizeof(node));
temp = hashtable[i];
while (temp != NULL) //loop to print the linked list
{
if (temp->word != NULL) //**THIS IS WHERE VALGRIND IS POINTING THE ERROR TO BE**
{
printf("%s\n", temp->word);
temp = temp->next;
}
else break;
}
}
printf("\n");
fclose(dict);
printf("SUCCESS!!\n");
}
Where am I going wrong?? Please help
-----VALGRIND ERROR-----
jharvard#appliance (~/Dropbox/pset5): valgrind ./tempeol
==11035== Memcheck, a memory error detector
==11035== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==11035== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==11035== Command: ./tempeol
==11035==
antione
==11035== Conditional jump or move depends on uninitialised value(s)
==11035== at 0x80488CA: main (tempeol.c:68)
==11035==
beer
bear
caterpillar
cat
google
root
SUCCESS!!
==11035==
==11035== HEAP SUMMARY:
==11035== in use at exit: 582 bytes in 74 blocks
==11035== total heap usage: 75 allocs, 1 frees, 934 bytes allocated
==11035==
==11035== LEAK SUMMARY:
==11035== definitely lost: 480 bytes in 60 blocks
==11035== indirectly lost: 102 bytes in 14 blocks
==11035== possibly lost: 0 bytes in 0 blocks
==11035== still reachable: 0 bytes in 0 blocks
==11035== suppressed: 0 bytes in 0 blocks
==11035== Rerun with --leak-check=full to see details of leaked memory
==11035==
==11035== For counts of detected and suppressed errors, rerun with: -v
==11035== Use --track-origins=yes to see where uninitialised values come from
==11035== ERROR SUMMARY: 30 errors from 1 contexts (suppressed: 0 from 0)
Valgrind shows 30 errors. My hashtable is size 30. So feel the problem should be somewhere there. But I can't figure out why?
Your initialization of the hashtable entries isn't initializing the field word, that is what valgrind is complaining about.
Additionally your code seems to have other problems. E.g the malloc in the line just before is immediately overwritten and thus this memory leaks. Also the return of malloc shouldn't be cast. Avoid casts whenever you can, think of casts as "casting a spell". As long as you don't know what that does, avoid it.

Resources