1

メモリの割り当てと割り当て解除のために書いた 2 つの関数が機能するかどうかを確認するコードを書いていました。2つの機能は本質的に

int createBaseName(char ***imageName, char **groupName, char *name)
{
    *imageName = calloc(BASELINEC, sizeof(char *)); //This is a 2D array (array of str)
    *groupName = calloc(MINILINE, sizeof(char)); // This is a 1D array (just an str)

    sprintf(*groupName, "%s_BGr.fbi", name);
    for(bb = 0; bb < BASELINEC; bb++) {
       (*imageName)[bb]  = (char *)calloc(MINILINE, sizeof(char));
        if (bb < 9)
           sprintf((*imageName)[bb], "%s_BIm_00%d.fbi", name, bb+1);
        else if (bb < 99) 
           sprintf((*imageName)[bb], "%s_BIm_0%d.fbi", name, bb+1);
        else
           sprintf((*imageName)[bb], "%s_BIm_%d.fbi", name, bb+1);
   }
   return 0;
}

int freeBaseName(char **imageName, char *groupName)
{
   int  bb;

   for(bb = 0; bb < BASELINEC; bb++)
      free(imageName[bb]);

   free(imageName);
   free(groupName);

   return 0;
}

これらの 2 つの関数をチェックするために私が書いたプログラムで、誤って とcreateBaseNamefreeBaseName次々に呼び出してから、 と出力しようとしていましimageNamegroupName。これにより、正常に印刷され、セグメンテーション違反が発生する前にgroupName、400 個の名前のうち約 120 個が正常にimageName印刷されました。

質問:freeメモリの -ingが機能しなかったのはなぜですか? それともメモリ解放に時間がかかりますか?

4

4 に答える 4

2

あなたfreeが記憶を持っているとき、あなたはそれを制御できなくなります。他の用途のためにメモリを解放します。他の関数や変数によってすぐに上書きまたは占有されることはありません。ただし、いつでも他の関数または変数で使用できます。それまでは、メモリにアクセスできます。しかし、それが他の人によっていつ使用されるかについては確信が持てないため、動作未定義です。

  • 同じ変数を使用してメモリにアクセスできないようにしたい場合は、それらをNULLafter freeing に設定します。
于 2013-04-23T09:20:42.380 に答える
2

free()関数は、メモリ ブロックを「空き」としてマークするだけです。つまり、いつでも他の機能で使用できるということです。次回このメモリブロックを取得するプログラムによって処理されるはずなので、メモリをクリーンアップしません。

あなたが実際にしたことは、未定義の動作です。

于 2013-04-23T08:48:29.523 に答える
1

メモリを解放するとき、ポインタはまだ割り当てられたメモリを指しており、その内容は他のデータによって上書きされる (または上書きされない) 可能性があります。これが、時々機能するように見える理由です。未定義の動作は、まあ、未定義になる傾向があります。

于 2013-04-23T08:51:09.460 に答える
1

freeメモリを再利用できるように解放されていることを示します。メモリをfree再度使用しないようにする責任があります。解放後もメモリがそのまま残っている可能性があるため、groupName印刷は問題ありません。ただし、再割り当てされた可能性もあるため、セグメンテーション違反が発生しますimageName

于 2013-04-23T08:48:47.623 に答える