32

acプログラムを実行すると、次のエラーが発生します。

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

これは、プログラムの最後に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;
}

これは次のようにコンパイルされます。

gcc -Wall -g -lm test.c

Valgrind:

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

与える:

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

私は自分の記憶を自動的に管理しない言語の経験はあまりありませんが(したがって、この演習では少し学びます)、行き詰まっています。どんな助けでもいただければ幸いです。

このコードは、アディティブオーディオシンセサイザーの一部であると想定されています。その点で、それは機能し、ptrに格納された正しい出力を提供します。

ありがとう。

4

4 に答える 4

26
double *ptr = malloc(sizeof(double *) * TIME);
/* ... */
for(tcount = 0; tcount <= TIME; tcount++)
                         ^^
  • アレイを踏み越えています。要素<=を変更<または割り当てる SIZE + 1
  • あなたmallocは間違っています、あなたはsizeof(double)代わりに 欲しいでしょうsizeof(double *)
  • コメントとしてouah、破損の問題に直接関連していませんが、*(ptr+tcount)初期化せずに使用しています

  • ptr[tcount]スタイルノートと同じように、代わりに使用することをお勧めします*(ptr + tcount)
  • あなたはすでに知っているので、あなたは本当にmalloc+する必要はありませんfreeSIZE
于 2012-09-01T19:39:08.117 に答える
7

この行を変更します

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

double *ptr = malloc(sizeof(double) * TIME);
于 2012-09-01T19:39:39.893 に答える
4

1-malloc()が間違っています。
2-割り当てられたメモリの境界を超えています
3-割り当てられたメモリを初期化する必要があります

これが必要なすべての変更を加えたプログラムです。コンパイルして実行しました...エラーや警告はありません。

#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;
}
于 2012-09-01T19:46:26.183 に答える
3

すべてのコードをチェックしませんでしたが、エラーはmalloc呼び出しにあると思います。交換する必要があります

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

にとって

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

ダブルにサイズを割り当てたいので(ダブルへのポインタのサイズではありません)。

于 2012-09-01T19:43:35.740 に答える