ページ 1 / 1
メモリーを解放する方法
Posted: 2014年3月16日(日) 09:38
by たかお
こんにちは。
現在わたしはC+DXライブラリとVisual Studio Express 2012でRPGを製作しています。
配列の要素数を動的に変更したいと考え、malloc関数を使っているのですが、確保したアドレスを解放するときにエラーがでます。
コード:
GameScene GameTest(){
int items[2] = {3,4};
int itemSu = 2;
char** itemName = (char**)malloc((sizeof (char)) * (itemSu+1));
Item_GetItemName(items,itemSu,itemName);
//Chara_DrawInfo(items);
if(itemSu > 0){
free(items);
free(itemName);
}
return GAME_TEST;
}
コード:
void Item_GetItemName(int id[],int kazu,char* itemName[]){
//kazu分だけchar型配列を生成
for(int i=0; i<kazu; i++){
itemName[i] = item_box[id[i]].name;
}
itemName[kazu] = NULL;
}
dbgheap.c
ここで「ブレークポイントが発生した」というエラーがでる。
コード:
extern "C" _CRTIMP int __cdecl _CrtIsValidHeapPointer(
const void * pUserData
)
{
if (!pUserData)
return FALSE;
if (!_CrtIsValidPointer(pHdr(pUserData), sizeof(_CrtMemBlockHeader), FALSE))
return FALSE;
return HeapValidate( _crtheap, 0, pHdr(pUserData) );
}
何が問題なのでしょうか?教えていただきたいです。
Re: メモリーを解放する方法
Posted: 2014年3月16日(日) 09:47
by softya(ソフト屋)
配列化されたポインタの解放ですので、ちゃんとmallocした数だけforループで回しながら解放しないとダメですね。
あとitemsはmallocしていないのでfreeしないでください。
free( itemName ); ← 先にこちらを解放
free( itemName ); ← こちらは後で。
Re: メモリーを解放する方法
Posted: 2014年3月16日(日) 10:33
by box
たかお さんが書きました:
コード:
char** itemName = (char**)malloc((sizeof (char)) * (itemSu+1));
私が知っている限りにおいて、
malloc()の戻り値を
char **
にキャストするのであれば、
malloc()の引数の型は
char *
つまり、キャストしたい型よりも「1段だけ」低いレベル
でなければならないと思うのですが、いかがでしょうか。
よって、私が知っている限りにおいて、上のコードは
コード:
char** itemName = (char**)malloc((sizeof (char*)) * (itemSu+1));
または
コード:
char* itemName = (char*)malloc((sizeof (char)) * (itemSu+1));
のどちらかになるような気がします。いかがでしょうか。
Re: メモリーを解放する方法
Posted: 2014年3月16日(日) 10:45
by たかお
softyaさん、boxさん回答ありがとうございます!
最終的に itemName[itemSu + 1] = {"アイテム名1","アイテム名2",NULL}; このような形にしたいので、
コード:
char** itemName = (char**)malloc((sizeof (char*)) * (itemSu+1));
こちらの書き方にするべきですね。ありがとうございました。
しかし、mallocした数だけ解放しなければならない。ということは理解したのですが、疑問が生まれました。
私は、
http://d.hatena.ne.jp/tondol/20090713/1247426321 のサイトを参考にしているのですが、
このサイトの「各行のデータを保持する配列を連続した領域で確保」では、配列を生成しているにも関わらず
一度だけしかメモリを解放していません。他のやり方と何が違うのでしょうか。
Re: メモリーを解放する方法
Posted: 2014年3月16日(日) 10:50
by みけCAT
softya(ソフト屋) さんが書きました:配列化されたポインタの解放ですので、ちゃんとmallocした数だけforループで回しながら解放しないとダメですね。
あとitemsはmallocしていないのでfreeしないでください。
free( itemName ); ← 先にこちらを解放
free( itemName ); ← こちらは後で。
今回のコードでは、itemNameをfreeする必要はないと思いますが、違いますでしょうか?
item_box.nameをfreeする必要があるのでしたら、そのように書かないと、
二重にfreeしたり、freeする必要があるものをfreeしなかったりする事故の原因になると思います。
Re: メモリーを解放する方法
Posted: 2014年3月16日(日) 11:06
by softya(ソフト屋)
失礼しました。
char**から早とちりしてchar*もmallocしていると思い込んだようです。
やりたいことからすると必要そうではありますが、現在は行われていない様ですね。
ということで必要な文字列の長さを確保してのmallocも必要です。
Re: メモリーを解放する方法
Posted: 2014年3月16日(日) 11:20
by たかお
先ほど指摘された書き方
コード:
char** itemName = (char**)malloc((sizeof (char*)) * (itemSu+1));
にしたところ、期待通りの結果がでました。
みなさん回答ありがとうございました。
Re: メモリーを解放する方法
Posted: 2014年3月16日(日) 13:30
by softya(ソフト屋)
あれ? 文字列のポインタをコピーしているだけでしたか。
それなら、free( itemName ); だけでOKです。
忙しい合間に書き込むとダメですね。すいません。