[c] double free or corruption (!prev) error in c program

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.

This question is related to c free

The answer is


I didn't check all the code but my guess is that the error is in the malloc call. You have to replace

 double *ptr = malloc(sizeof(double*) * TIME);

for

 double *ptr = malloc(sizeof(double) * TIME);

since you want to allocate size for a double (not the size of a pointer to a double).


1 - Your malloc() is wrong.
2 - You are overstepping the bounds of the allocated memory
3 - You should initialize your allocated memory

Here is the program with all the changes needed. I compiled and ran... no errors or warnings.

#include <stdio.h>
#include <stdlib.h> //malloc
#include <math.h>  //sine
#include <string.h>

#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);
     //memset( ptr, 0x00, sizeof(double) * TIME);  may not always set double to 0
    for( tcount = 0; tcount < TIME; tcount++ )
    {
         ptr[tcount] = 0; 
    }

    tcount = 0;
    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;
}

Change this line

double *ptr = malloc(sizeof(double *) * TIME);

to

double *ptr = malloc(sizeof(double) * TIME);