ページ 11

メモリの解放についての意味がわかりません。

Posted: 2009年6月18日(木) 01:06
by チャック
メモリを解放するという意味がわかりません。
参考書にしたがって取得したメモリ領域は解放しているのですが、
解放した領域を戻り値として呼び出し元に返す場合どこでメモリを解放すればいいのでしょうか。

やりたいことは、VBのMID関数を作ることで、text文字列のstartpoint~endpointまでを取り出そうとしています。

wchar_t *MyStrncatFunc(wchar_t *text, int startpoint, int endpoint){
    int i;
    int text_size;
    wchar_t *p;
    
    // text文字列の長さを取得
    text_size = WideStringReturnFunction(text);

    // エラー処理
    if((startpoint>endpoint) | (endpoint > text_size)){
        puts("[MyStrncatFunc:001]引数に問題があります。");
        exit(1);
    }
    
    // 領域取得(text文字数分の領域取得)
    p = (wchar_t *)malloc((text_size+1) * sizeof(wchar_t));
    if(p == NULL){
        puts("[MyStrncatFunc:002] : 領域の確保に失敗しました。");
        exit(1);
    }
    
    // startpoint~endpointまでの文字をコピー
    for(i=startpoint; i<=endpoint; i++){
        *(p+i) = *(text+i);
    }
    
    // 終端文字
    *(p+i) = L'\0';

    // ★001★:ここで取得した領域を開放すると、呼び出し元に切り出した文字列が表示されない。

    return p;

    // ★002★:ここでメモリ解放しても、通らない。

}

Re:メモリの解放についての意味がわかりません。

Posted: 2009年6月18日(木) 05:45
by toyo
必要な間は開放しません
要らなくなった時点で呼び出し側で開放します
wchar_t *str = MyStrncatFunc(text, 10, 20);
// 処理
// 不要になったら
free(str);
str = NULL;

Re:メモリの解放についての意味がわかりません。

Posted: 2009年6月18日(木) 12:24
by ouh
C言語でやるなら、
・元の文字列へのポインタ
・startpoint
・endpoint ではなく文字数
・受け取りバッファへのポインタ
・受け取りバッファのサイズ
を引数にして、呼び出し側ではこんな感じにするほうがいいんじゃないかな?

MID関数の名前を mid とすると、

wchar_t *text = L"abcdefg";
wchar_t buf[4];
mid(text, 1, 3, buf, 6);

これで text[1] から text[3] までが buf にコピーされるように作る。
で、関数内で領域を確保したりしないし、確保した領域へのポインタを
返したりもしない。

呼び出し側に解放させるような作りはよくないと思うんです。

mid の中身まで書くのはめんどいので頭だけ書きますけど、
text は const にして、

int mid(const wchar_t *text int startpoint, int n, wchar_t *buf, const int nSize) {
}

とか。

Re:メモリの解放についての意味がわかりません。

Posted: 2009年6月18日(木) 12:26
by ouh
すいません、間違えました。

mid(text, 1, 3, buf, 6);

じゃなくて

mid(text, 1, 3, buf, 4);

です。

Re:メモリの解放についての意味がわかりません。

Posted: 2009年6月19日(金) 01:21
by チャック
ありがとうございます。
月曜に学校で実行して試してみて結果を報告します。

Re:メモリの解放についての意味がわかりません。

Posted: 2009年6月19日(金) 07:32
by toyo
>呼び出し側に解放させるような作りはよくないと思うんです。
オブジェクトを確保してポインタを返す関数はいっぱいありますよ
標準関数でもstrdupとかあります