2012-09-01 14 views
13

me sale el error siguiente cuando se ejecuta el programa de corriente alterna (Ant):doble liberación o corrupción de error en el programa c

*** glibc detected *** ./a.out: double free or corruption (!prev): 0x080b8008 *** 

Creo que esto se debe a free() se llama al final del programa, pero no puedo averiguar dónde se está liberando la memoria malloc antes de esto. Aquí está el código:

#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; 
} 

Esto se compila con:

gcc -Wall -g -lm test.c 

Valgrind:

valgrind --leak-check=yes ./a.out 

da:

==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) 

no tengo mucha experiencia con idiomas que no manejan su propio yo Mory automáticamente (de ahí este ejercicio en c para aprender un poco) pero estoy atascado. Cualquier ayuda sería apreciada.

Se supone que el código es parte de un sintetizador de audio aditivo. En ese sentido, funciona y da el resultado correcto almacenado en ptr.

Gracias.

Respuesta

19
double *ptr = malloc(sizeof(double *) * TIME); 
/* ... */ 
for(tcount = 0; tcount <= TIME; tcount++) 
         ^^ 
  • usted está sobrepasando la matriz. O bien cambiar a <=< o alloc SIZE + 1 elementos
  • Su malloc está mal, querrá sizeof(double) en lugar de sizeof(double *)
  • Como ouah comentarios, aunque no directamente relacionado con su problema de la corrupción, que está utilizando *(ptr+tcount) sin inicializar que

  • Al igual que un sin estilo te, es posible que desee utilizar en lugar de ptr[tcount]*(ptr + tcount)
  • Usted realmente no necesita malloc + free puesto que ya sabe SIZE
+0

También '* (ptr + tcount) + = sine;' pero la matriz nunca se inicializa. – ouah

+0

@ouah Buena llamada. Este programa tiene más agujeros que un queso suizo. – cnicutar

+0

queso suizo de hecho! Gracias por tu ayuda. Parece que todavía tengo mucho camino por recorrer para descifrar punteros y malloc. – user1640921

6

cambiar esta línea

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

a

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

No revisé todo el código, pero creo que el error está en la llamada malloc.Usted tiene que reemplazar

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

para

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

ya que desea asignar el tamaño de una habitación doble (no el tamaño de un puntero a una doble).

4

1 - Su malloc() es incorrecto.
2 - Usted es sobrepasar los límites de la memoria asignada
3 - Usted debe inicializar la memoria asignada

Este es el programa con todos los cambios necesarios. Recopilé y ejecuté ... sin errores ni advertencias.

#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; 
} 
+1

Acerca del 'memset': todos los bits 0 no necesariamente significan que el valor doble almacenado es 0. – cnicutar

+0

@cnicutar ¿Es porque las representaciones de variables en coma flotante están definidas por la implementación? – Chimera

+0

Es porque no hay garantía de que todos los formatos de coma flotante tengan 0 representado como todos los bits 0. – cnicutar

Cuestiones relacionadas