I get the following error when running a c program:
*** glibc detected *** ./a.out: double free or corruption (!prev): 0x080b8008 ***
I believe this is due to free() being called at the end of the program, but I can't figure out where the malloc'd memory is being freed prior to this. Here is the code:
#include <stdio.h> #include <stdlib.h> //malloc #include <math.h> //sine #define TIME 255 #define HARM 32 int main (void) { double sineRads; double sine; int tcount = 0; int hcount = 0; /* allocate some heap memory for the large array of waveform data */ double *ptr = malloc(sizeof(double *) * TIME); if (NULL == ptr) { printf("ERROR: couldn't allocate waveform memory!\n"); } else { /*evaluate and add harmonic amplitudes for each time step */ for(tcount = 0; tcount <= TIME; tcount++){ for(hcount = 0; hcount <= HARM; hcount++){ sineRads = ((double)tcount / (double)TIME) * (2*M_PI); //angular frequency sineRads *= (hcount + 1); //scale frequency by harmonic number sine = sin(sineRads); *(ptr+tcount) += sine; //add to other results for this time step } } free(ptr); ptr = NULL; } return 0; }
This is compiled with:
gcc -Wall -g -lm test.c
Valgrind:
valgrind --leak-check=yes ./a.out
gives:
==3028== Memcheck, a memory error detector ==3028== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. ==3028== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info ==3028== Command: ./a.out ==3028== ==3028== Invalid read of size 8 ==3028== at 0x8048580: main (test.c:25) ==3028== Address 0x41ca420 is 1,016 bytes inside a block of size 1,020 alloc'd ==3028== at 0x4024F20: malloc (vg_replace_malloc.c:236) ==3028== by 0x80484F8: main (test.c:15) ==3028== ==3028== Invalid write of size 8 ==3028== at 0x8048586: main (test.c:25) ==3028== Address 0x41ca420 is 1,016 bytes inside a block of size 1,020 alloc'd ==3028== at 0x4024F20: malloc (vg_replace_malloc.c:236) ==3028== by 0x80484F8: main (test.c:15) ==3028== ==3028== ==3028== HEAP SUMMARY: ==3028== in use at exit: 0 bytes in 0 blocks ==3028== total heap usage: 1 allocs, 1 frees, 1,020 bytes allocated ==3028== ==3028== All heap blocks were freed -- no leaks are possible ==3028== ==3028== For counts of detected and suppressed errors, rerun with: -v ==3028== ERROR SUMMARY: 8514 errors from 2 contexts (suppressed: 14 from 7)
I don't have much experience with languages which don't manage their own memory automatically (hence this exercise in c to learn a bit) but am stuck. Any help would be appreciated.
The code is supposed to be part of an additive audio synthesiser. In that respect it does work and gives the correct output stored in ptr.
Thanks.
Description. Double free errors occur when free() is called more than once with the same memory address as an argument. Calling free() twice on the same value can lead to memory leak.
A double free in C, technically speaking, leads to undefined behavior. This means that the program can behave completely arbitrarily and all bets are off about what happens.
You can use gdb, but I would first try Valgrind. See the quick start guide. Briefly, Valgrind instruments your program so it can detect several kinds of errors in using dynamically allocated memory, such as double frees and writes past the end of allocated blocks of memory (which can corrupt the heap).
Double Free A simple technique to avoid this type of vulnerability is to always assign NULL to a pointer after it has been freed. Subsequent attempts to free a null pointer will be ignored by most heap managers.
double *ptr = malloc(sizeof(double *) * TIME); /* ... */ for(tcount = 0; tcount <= TIME; tcount++) ^^
<=
to <
or alloc SIZE + 1
elementsmalloc
is wrong, you'll want sizeof(double)
instead of sizeof(double *)
ouah
comments, although not directly linked to your corruption problem, you're using *(ptr+tcount)
without initializing itptr[tcount]
instead of *(ptr + tcount)
malloc
+ free
since you already know SIZE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With