1. ホーム
  2. c

[解決済み] C言語のポインタをNULLに初期化することは可能ですか?

2023-03-08 23:57:54

質問

というようなことを書いていたのですが

char *x=NULL;

という前提で

 char *x=2;

を作成すると char へのポインタはアドレス 2 になります。

しかし GNU C プログラミングチュートリアル には、次のように書かれています。 int *my_int_ptr = 2; は整数値を格納します。 2 にある任意のランダムなアドレスに my_int_ptr に割り当てられます。

これはつまり、私自身の char *x=NULL の値が何であれ NULL にキャストしています。 char はメモリ上のランダムなアドレスになります。

とはいえ

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

int main()
{
    char *x=NULL;

    if (x==NULL)
        printf("is NULL\n");

    return EXIT_SUCCESS;
}

は、実際に、印刷します。

はNULL

をコンパイルして実行すると、未定義の動作、あるいは少なくとも規定外の動作に依存しているのではないかと心配になり、次のように書きます。

char *x;
x=NULL;

の代わりに

どのように解決するのですか?

<ブロッククオート

C 言語のポインターを NULL に初期化することは可能ですか?

TL;DR はい、とても。


ガイドに書かれている実際の主張 は次のように読みます。

<ブロッククオート

一方、単一の初期割り当てだけを使用する場合。 int *my_int_ptr = 2; で指されるメモリロケーションの内容を埋めようとします。 my_int_ptr が指すメモリ位置の内容を値 2 で埋めようとする。このため my_int_ptr はゴミで埋まっているので、任意のアドレスにすることができます。[...]

さて、彼らは は間違っている、あなたは正しい。

ステートメントについては、( は、ポインタから整数への変換は実装で定義された動作であるという事実を無視し )

int * my_int_ptr = 2;

my_int_ptr は変数(のポインタ型)です。 int へのポインタ)であり、それ自身のアドレス(タイプ:整数へのポインタのアドレス)を持っています。 2 の値を その のアドレスに変換します。

今すぐ my_int_ptr はポインタ型であるため、次のように言えます。 を指している を指すと言えます。 によって指される に保持されている値 my_int_ptr . つまり、本質的に値 の値を代入しているのであって、ポインタが指すメモリ位置の値を代入しているわけではありません。

というわけで、結論から言うと

 char *x=NULL;

ポインタ変数を初期化する xNULL ではなく の値ではなく、ポインターの指すメモリアドレスにある .

これは と同じ として

 char *x;
 x = NULL;    


拡張。

さて、厳密に準拠すると、次のような文になります。

 int * my_int_ptr = 2;

は制約違反を含むため、違法です。はっきり言って

  • my_int_ptr はポインタ変数で、型は int *
  • は整数の定数です。 2 は型が int を持ちます。

で説明されているように、これらは "compatible" 型ではないので、この初期化は§6.5.16.1P1章で述べられている単純代入のルールに違反しているため、無効となります。 Lundin の回答 .

初期化が単純な代入制約にどのようにリンクされているかに興味がある人のために、引用します。 C11 章§6.7.9, P11

スカラのイニシャライザは,一つの式とし,オプションで中括弧で囲む。オブジェクトの初期値は オブジェクトの初期値は、(変換後の)式の値である。 と同じ型 単純な代入と同じ制約と変換が適用され、スカラの型は修飾されていないバージョンとみなされます。 の型は宣言された型の非限定版であるとします。