Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalid read of size 8 - Valgrind + C

Tags:

c

valgrind

Valgrind reports error Invalid read of size 8 in the following code.

I have an array declared like,

struct symbol *st[PARSER_HASH_SIZE]; 

When my program is initialized, all the elements in this array are initailzied as 0.

memset(&st[0], 0, sizeof(st)); 

My program creates instances of struct symbol and inserts into the above array depending on the hash value. So few of the elements in this array will be NULL and others will be valid value.

The following code tries to delete the allocated items and valgrind complains at the line, sym = st[i]; sym != NULL; sym = sym->next

struct symbol *sym = NULL;  /* cleaning the symbol table entries */ for(i = 0; i < PARSER_HASH_SIZE; i++) {     for(sym = st[i]; sym != NULL; sym = sym->next) { /* <-- Valgrind complains here */         free(sym);     } } 

I am trying to understand the reason for this error.

Any help would be great!

like image 524
Navaneeth K N Avatar asked Oct 27 '10 17:10

Navaneeth K N


People also ask

What is invalid read of size 8 in C?

An Invalid read means that the memory location that the process was trying to read is outside of the memory addresses that are available to the process. size 8 means that the process was trying to read 8 bytes. On 64-bit platforms this could be a pointer, but also for example a long int.

How do I fix invalid read?

Invalid reads and writes can be fixed by making sure to set any unused pointer to NULL and being careful about the memory locations that you access in your code. int x; printf("x = %d\n\r", x);

Why does Valgrind report that the invalid write is of size 8 be precise?

1 Answer. Show activity on this post. It looks like Valgrind is complaining because you have only allocated 1780 bytes for the PetscObject, and this 8-byte write (starting at byte 1776) is enough to write into memory you didn't allocate.

What is invalid read of size 4 in C?

Invalid read It means that we tried to read 4 bytes, starting at adress 0x0 (for those of you who don't know it yet, NULL is actually a pointer to adress 0x0, so we tried to read 4 bytes starting from NULL).


2 Answers

The problem is that you're freeing the sym, then trying to access a value from the (now-freed) data: sym->next.

You probably want something like this for the inner loop:

struct symbol *next_sym = NULL;  for(sym = st[i]; sym != NULL; ) {     next_sym = sym->next;     free(sym);     sym = next_sym; } 
like image 100
ZoogieZork Avatar answered Sep 23 '22 17:09

ZoogieZork


also its not clear if you array is meant to contain structs or pointers to structs

struct symbol *st[PARSER_HASH_SIZE]; 

says its an array of pointers to structs. But then you say

"When my program is initialized, all the elements in this array are initailzied as 0."

memset(&st[0], 0, sizeof(st)); 

This is treating the entries like structs

to clear the array do

for (int i = 0; i < PARSER_HASH_SIZE; i++) {     st[i] = 0; } 
like image 33
pm100 Avatar answered Sep 25 '22 17:09

pm100