kagamihogeの日記

kagamihogeの日記です。

スタックとヒープ

わかっているようで全然わかっていなかった。これじゃJava厨と呼ばれても仕方ない・・・。

プログラマのためのメモリとポインタの基礎
このテの内容を扱った文献はたくさんあるけど、とりあえずこれをメモ。

最近ちょっとCを触っているのだが、いわゆるリスト処理を書いてるときにVCのデバッガが妙なアサーションエラーを吐き出してきた。内容は、_CrtIsValidHeapPointerがアサーションでfalseを検知だという。
関連:http://msdn2.microsoft.com/ja-jp/library/ys6cfhhh(VS.80).aspx

このアサーションエラーは、下のようなコードでfree()するときに出てきた。解放対象の領域がヒープではないから危険だぞ、と言っているらしい。ナニソレ?と思ったけど、どうやら積んであるスタック上の領域を解放しようとしてるらしい。

NODE *set_node_data(char *str) {
LIST_NODE *node = alloc_node();/*リストノード領域の割当をしている*/
node->str = str;
/*
node->str = malloc(strlen(str) + 1);
strcpy(node->str, str);
*/
return node;
}

void free(LIST_NODE *node) {
free(node->str);
free(node);
}

int main(int argc, char[] *argc) {
LIST_NODE *node = set_node_data("hoge");
...
free(node);
}

必要な部分だけテキトーに抜き出してきてるんでちょっとアレなコードだけど・・・。

重要なのは赤マークつけた行。node->strが指している先は、main関数のスタック中の領域("hoge")なのでヒープではない。なので、free(node->str)するときに「それはヒープじゃないからヤバイ」と怒られたわけです。つまりはコメント化してある場所のように書かないとダメ。

メモリがどんな風に使われてるのか、わかってなかったのが敗因。Javaもメモリ上の動きは知っておかないと色々マズイ点はあるんで、ある程度理解はしてたつもりだけど・・・全然だめだね、この程度じゃ。

やっぱJavaが楽でいいさ・・・。