5

thisによると、無効なポインターの値を取得することは、C++ の実装定義の動作です。ここで、次の C プログラムを考えてみましょう。

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    int* p=(int*)malloc(sizeof(int));
    *p=3;
    printf("%d\n",*p);
    printf("%p\n",(void*)p);
    free(p);
    printf("%p\n",(void*)p); // Is this undefined or implementation defined in behaviour C? 
}

しかし、Cでも動作は同じですか?上記の C プログラムの動作は未定義ですか、それとも実装定義ですか? C99/C11 標準はこれについて何と言っていますか? C99 と C11 で動作が異なる場合は教えてください。

4

4 に答える 4

7

Andrew Henleの答えを拡張する:

C99 標準 6.2.4 から:

オブジェクトには、その寿命を決定する保存期間があります。保存期間には、静的、自動、割り当ての 3 つがあります。割り当てられたストレージについては、7.20.3 で説明されています。[…]ポインターの値は、それが指している (または直前の) オブジェクトがその存続期間の終わりに達すると、不確定になります。

次に、7.20.3.2 で: 標準はmalloc()、 、calloc()およびの記述を続けfree()、そのことに言及します。

このfree関数は、 が指すスペースのptr割り当てを解除します。

3.17.2:

不定値

未指定の値またはトラップ表現

6.2.6.1.5:

特定のオブジェクト表現は、オブジェクト タイプの値を表す必要はありません。オブジェクトの格納された値がそのような表現を持ち、文字型を持たない左辺値式によって読み取られる場合、動作は未定義です。[…] このような表現はトラップ表現と呼ばれます。

ポインターが不定になり、不定値がトラップ表現になる可能性があり、左辺値である変数があり、左辺値トラップ表現の読み取りが未定義であるため、はい、動作が未定義になる可能性があります。

于 2015-11-07T17:06:22.860 に答える
4

C 標準のセクション 6.2.4に従って:

オブジェクトの存続期間は、プログラム実行の中で、そのオブジェクト用にストレージが確保されることが保証されている部分です。オブジェクトは存在し、一定のアドレスを持ち、最後に格納された値を存続期間を通じて保持します。オブジェクトがその有効期間外に参照された場合、動作は未定義です。 ポインターの値は、それが指している (または直前の) オブジェクトがその有効期間の終わりに達すると、不確定になります

于 2015-11-07T16:21:09.180 に答える
-2

コメントからの続きです。それが有効か無効かについての混乱は、ポインターのどの側面について尋ねられているかを取り囲んでいると思います。上記では、free(p);が指すメモリ ブロックの開始アドレスに影響しますが、それ自体pのアドレスには影響せず、有効なままです。p(値として)によって保持されるアドレスはなくなり、p再割り当てされるまで不確定のままになります。短い例が役に立ちます:

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

int main (void) {

    int *p = NULL;

    printf ("\n the address of 'p' (&p) : %p\n", &p);

    p = malloc (sizeof *p);
    if (!p) return 1;

    *p = 3;

    printf (" the address of 'p' (&p) : %p   p points to %p   with value  %d\n",
            &p, p, *p);

    free (p);

    /* 'address of p' unchanged, p itself indeterminate until reassigned */
    printf (" the address of 'p' (&p) : %p\n\n", &p);

    p = NULL;  /* p no longer indeterminate and can be allocated again */

    return 0;
}

出力

$ ./bin/pointer_addr

 the address of 'p' (&p) : 0x7fff79e2e8a0
 the address of 'p' (&p) : 0x7fff79e2e8a0   p points to 0x12be010   with value  3
 the address of 'p' (&p) : 0x7fff79e2e8a0

pそれ自体のアドレスは、mallocまたはによって変更されませんfree。影響を受けるのはの値ですp(より正確には、アドレスpはその値として保存されます)。の時点freeで、アドレスpストアはシステムに解放され、 からアクセスできなくなりますp。明示的に再割り当てp = NULL; pすると、不確定ではなくなり、再度割り当てに使用できます。)

于 2015-11-07T16:44:36.770 に答える