Cプログラムを実行すると、次のエラーが表示されます。
*** 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 --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)
私は自分の記憶を自動的に管理しない言語についてはあまり経験がありません(したがって、このcの練習で少し学習します)が、行き詰っています。任意の助けをいただければ幸いです。
コードは、付加的なオーディオシンセサイザーの一部であると想定されています。その点で機能し、ptrに保存された正しい出力を提供します。
ありがとう。
_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
を既に知っているので、free
+ SIZE
は本当に必要ありません。この行を変更
double *ptr = malloc(sizeof(double *) * TIME);
に
double *ptr = malloc(sizeof(double) * TIME);
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;
}
すべてのコードをチェックしたわけではありませんが、エラーはmalloc呼び出しにあると推測されます。交換する必要があります
double *ptr = malloc(sizeof(double*) * TIME);
for
double *ptr = malloc(sizeof(double) * TIME);
doubleのサイズ(doubleへのポインターのサイズではない)を割り当てたいため。