C free (): invalid pointer

I teach myself C. My goal is to create a C function that simply scans the query string and breaks into ampersand and equal sign. I am stuck with this error from Valgrind.

==5411== Invalid free() / delete / delete[] / realloc() ==5411== at 0x402AC38: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==5411== by 0x804857C: main (leak.c:28) ==5411== Address 0x420a02a is 2 bytes inside a block of size 8 free'd ==5411== at 0x402AC38: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==5411== by 0x804857C: main (leak.c:28) ==5411== ==5411== ==5411== HEAP SUMMARY: ==5411== in use at exit: 0 bytes in 0 blocks ==5411== total heap usage: 1 allocs, 2 frees, 8 bytes allocated ==5411== ==5411== All heap blocks were freed -- no leaks are possible ==5411== ==5411== For counts of detected and suppressed errors, rerun with: -v ==5411== ERROR SUMMARY: 20 errors from 9 contexts (suppressed: 0 from 0) 

and backtrace:

 *** Error in `./leak': free(): invalid pointer: 0x08c1d00a *** ======= Backtrace: ========= /lib/i386-linux-gnu/libc.so.6(+0x767c2)[0xb75f17c2] /lib/i386-linux-gnu/libc.so.6(+0x77510)[0xb75f2510] ./leak[0x804857d] /lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0xb7594905] ./leak[0x8048421] ======= Memory map: ======== 08048000-08049000 r-xp 00000000 08:05 262764 /home/danny/dev/c-qs-parser/leak 08049000-0804a000 r--p 00000000 08:05 262764 /home/danny/dev/c-qs-parser/leak 0804a000-0804b000 rw-p 00001000 08:05 262764 /home/danny/dev/c-qs-parser/leak 08c1d000-08c3e000 rw-p 00000000 00:00 0 [heap] b757a000-b757b000 rw-p 00000000 00:00 0 b757b000-b7729000 r-xp 00000000 08:05 1312132 /lib/i386-linux-gnu/libc-2.17.so b7729000-b772b000 r--p 001ae000 08:05 1312132 /lib/i386-linux-gnu/libc-2.17.so b772b000-b772c000 rw-p 001b0000 08:05 1312132 /lib/i386-linux-gnu/libc-2.17.so b772c000-b772f000 rw-p 00000000 00:00 0 b772f000-b774a000 r-xp 00000000 08:05 1312589 /lib/i386-linux-gnu/libgcc_s.so.1 b774a000-b774b000 r--p 0001a000 08:05 1312589 /lib/i386-linux-gnu/libgcc_s.so.1 b774b000-b774c000 rw-p 0001b000 08:05 1312589 /lib/i386-linux-gnu/libgcc_s.so.1 b774c000-b7750000 rw-p 00000000 00:00 0 b7750000-b7751000 r-xp 00000000 00:00 0 [vdso] b7751000-b7771000 r-xp 00000000 08:05 1312116 /lib/i386-linux-gnu/ld-2.17.so b7771000-b7772000 r--p 0001f000 08:05 1312116 /lib/i386-linux-gnu/ld-2.17.so b7772000-b7773000 rw-p 00020000 08:05 1312116 /lib/i386-linux-gnu/ld-2.17.so bfe93000-bfeb4000 rw-p 00000000 00:00 0 [stack] Aborted (core dumped) 

Finally, here is the code:

 #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { //char p[] = "t=quote&k=id&v=10"; char p[] = "t=quote"; char* token; char* tk; char* s; unsigned short int found; s = strdup(p); if (s != NULL) { while ((token = strsep(&s, "&")) != NULL) { found = 0; printf("TOKEN: %s\n\n", token); while ((tk = strsep(&token, "=")) != NULL) { printf("TK: %s\n\n", tk); free(tk); } free(token); } } free(s); return 0; } 

thanks

+8
c pointers free valgrind
source share
3 answers

You are trying to free something that is not a pointer to a "free" memory address. Just because something is an address does not mean that you need or should release it.

There are two main types of memory that you seem to be confusing: the memory stack and heap memory.

  • Stack memory lives in real time function. This is a temporary space for things that should not grow too big. When you call the main function, it allocates some memory for your variables that you declared ( p , token , etc.).

  • Memory β€œA heap lives when you malloc it, when you are free . You can use a lot more heap memory than you can add memory. You also need to keep track of it - it's not as easy as a stack memory!

You have a few errors:

  • You are trying to free memory, not a bunch of memory. Do not do this.

  • You are trying to free the inside of a memory block. When you actually allocated a block of memory, you can only release it from the pointer returned by malloc . That is, only from the beginning of the block . You cannot free part of the block from the inside.

For your code here, you probably want to find a way to copy the corresponding piece of memory to another location ... say, another block of memory that you put aside. Or you can change the original string if you want (hint: char value 0 is a null terminator and tells functions like printf to stop reading the string).

EDIT: The malloc function allocates heap memory *.

"9.9.1 malloc and free functions

The C standard library provides an explicit allocator known as the malloc package. Programs allocate blocks from the heap by calling the malloc function. "

~ Computer Systems: A Programmer's Perspective, Second Edition, Bryant and O'Hallaron, 2011

EDIT 2: * Standard C does not actually indicate anything about a heap or stack. However, for those who study on the appropriate desktop / laptop computer, the distinction is probably unnecessary and confusing if anything, especially if you learn about how your program is stored and executed. When you find yourself working on something like an AVR microcontroller, as is the case with H2CO3, it’s worth noting all the differences that, from my own experience with embedded systems, greatly expand the memory allocation.

+21
source share

Where did you get the idea that you need free(token) and free(tk) ? You will not do it. strsep() does not allocate memory, it only returns pointers inside the original string. Of course, these are not pointers allocated by malloc() (or similar), therefore free() their behavior is undefined. You only need free(s) when you are done with the whole line.

Also note that you do not need dynamic allocation of memory at all in your example. You can generally avoid strdup() and free() simply writing char *s = p; .

+11
source share

You cannot call free on pointers returned from strsep . These are not separate lines, but only pointers to the string s that you have already selected. When you are done with s in general, you should free it, but you do not need to do this with strsep return values.

+3
source share

All Articles