2009/10/01

[memo] malloc, free(3)

http://www.linux.or.jp/JM/html/LDP_man-pages/man3/malloc.3.html

考えてみれば当たり前なんだけど、free(3) に渡すポインタは malloc(3) 等から返ってきたポインタ「そのもの」でなければならない。以下のコードは FreeBSD 6.4 Release だと実行時に「warning: modified (chunk-) pointer」という警告が出る。Linuxだとアボートする。

#include <stdio.h>
#include <stdlib.h>
static const int BUFSIZE = 256;
int main(int argc, char *argv[])
{
char *buffer = (char *)malloc(BUFSIZE);
if (buffer == NULL) {
fprintf(stderr, "out of memory");
return -1;
}
buffer++; // wrong.
free(buffer);
return 0;
}


バッファに構造体の中身をコピーするようなコードを書いているときに、上記のような間違いを犯したことがあるので記録しておく。

1 件のコメント:

Unknown さんのコメント...

mallocしたときに、mallocされたデータに関する情報が配列データの直前にあるって聞いたような気がして試してみました。

-------- ここから
#include <stdio.h>
#include <stdlib.h>

int main() {
for (int i = 0; i < 16; ++i) {
size_t* p = (size_t*)malloc(i * sizeof(size_t));
printf("%u\n", (unsigned int)p[-1]);
free(p);
}
return 0;
}
-------- ここまで

結果は、うちのマシンでは
-------- ここから
33
33
33
33
49
49
65
65
81
81
97
97
113
113
129
129
-------- ここまで

おそらく、「ヘッダサイズ(9Byte)+実際のデータサイズ」です。等差数列にはなっていないのでちょこっと工夫がされてるみたいですね。
reallocやってみると面白かったりするかもね。