c程序中的双重免费或损坏(!prev)错误

use*_*921 24 c free

运行ac程序时出现以下错误:

*** glibc detected *** ./a.out: double free or corruption (!prev): 0x080b8008 ***
Run Code Online (Sandbox Code Playgroud)

我相信这是因为在程序结束时调用了free(),但我无法弄清楚malloc内存在此之前被释放的位置.这是代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

这是编译的:

gcc -Wall -g -lm test.c
Run Code Online (Sandbox Code Playgroud)

Valgrind的:

valgrind --leak-check=yes ./a.out
Run Code Online (Sandbox Code Playgroud)

得到:

    ==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)
Run Code Online (Sandbox Code Playgroud)

我没有太多使用不自动管理自己内存的语言的经验(因此这项练习在c中学习了一下)但是卡住了.任何帮助,将不胜感激.

该代码应该是附加音频合成器的一部分.在这方面,它确实有效,并提供存储在ptr中的正确输出.

谢谢.

cni*_*tar 21

double *ptr = malloc(sizeof(double *) * TIME);
/* ... */
for(tcount = 0; tcount <= TIME; tcount++)
                         ^^
Run Code Online (Sandbox Code Playgroud)
  • 你超越了阵列.更改或 <=分配元素<SIZE + 1
  • malloc错了,你会想要sizeof(double)而不是 sizeof(double *)
  • 作为ouah评论,虽然没有直接与您的腐败问题相关联,但您使用*(ptr+tcount)时却没有初始化它

  • 就像样式注释一样,您可能希望使用ptr[tcount]而不是*(ptr + tcount)
  • 因为你已经知道,你真的不需要malloc+freeSIZE

  • 还有 `*(ptr+tcount) += sine;` 但数组从未初始化。 (2认同)
  • @ouah好的电话。该程序比瑞士奶酪的孔更多。 (2认同)

per*_*ain 6

改变这一行

double *ptr = malloc(sizeof(double *) * TIME);
Run Code Online (Sandbox Code Playgroud)

double *ptr = malloc(sizeof(double) * TIME);
Run Code Online (Sandbox Code Playgroud)