0

次のコードを検討してください (g++ でビルド):

#include <stdlib.h>
#include <stdio.h>

typedef struct {
    int a;
    int b;
    char c;
} memstr_t;

memstr_t *ptt_backup;

void mmm(memstr_t*& ptt)
{
    ptt = (memstr_t *)calloc(15, sizeof(memstr_t));
    ptt[0].a = 1;
    ptt[0].b = 2;
    ptt[0].c = 'c';
    ptt_backup = ptt;
}

void fff()
{
    free(ptt_backup);
}

int main(int argc, char *argv[])
{
    memstr_t *ptt;

    mmm(ptt);
    printf("%d %d %c\n", ptt[0].a, ptt[0].b, ptt[0].c);
    getchar();
    //fff();
    free(ptt); // same as fff()?
    printf("%d %d %c\n", ptt[0].a, ptt[0].b, ptt[0].c); //why works?
    getchar();
    return 0;
}

理解できない:

1) メモリを解放した後、2 番目の印刷で segfault が発生しないのはなぜですか? 割り当てた値をまだ取得していますmmm()

2)free()fff()は同じことをしていますか?

4

5 に答える 5

2

1)解放されたメモリを逆参照すると、何でもできます。そこにあるかもしれませんし、ないかもしれません。それは未定義の動作であり、猫にファックスを送ることを含め、何でもできます。

2) はい、free() と fff() はどちらも同じメモリ位置を指しているため、同じことをしています。

于 2013-06-14T13:01:14.063 に答える
1

2 番目の印刷では、無効になったポインターが使用されているため、動作が未定義になります。それが「機能する」とあなたが信じさせるものを含め、何が起こるかは何でも、それ以外の場合は、まったく別のものになる可能性があります. それをしないでください!

2: このコード フラグメントでは、同じ効果があります。

于 2013-06-14T13:02:22.260 に答える
0

callocメモリを割り当て、割り当てられたメモリへのポインタを返します。

mmm割り当てpttますptt_backup。両方とも同じ場所を指しています。(名前とニックネームがあるからといって、私のコピーが 2 つ作成されるわけではありません。私は、2 つの異なる名前でアクセスできる 1 人の人物です)

In fffyou are freeing ptt_backup( がfree指すメモリを ing と読みますptt_backup) は が指すpttメモリでもあります。これは、メモリが現在使用できないことを意味します。値を保持することはできますが、それに依存することは未定義です。この素敵な答えを参照してください 。ローカル変数のメモリはスコープ外でアクセスできますか?

printf("%d %d %c\n", ptt[0].a, ptt[0].b, ptt[0].c);常に機能するとは限りません。

次に、によって既に削除されている ( が指すメモリを ing と読む) と、述べfree(ptt)たように未定義の動作になります。freepttfff

free() 関数は、ptr が指すスペースの割り当てを解除します。つまり、追加の割り当てが可能になります。ptr が null ポインターの場合、アクションは発生しません。それ以外の場合、引数が calloc()、malloc()、[ADV] posix_memalign()、realloc()、または [XSI] strdup() 関数によって以前に返されたポインターと一致しない場合、またはスペースがによって割り当て解除された場合free() または realloc() への呼び出し、動作は未定義です。

于 2013-06-14T13:10:02.163 に答える