web-dev-qa-db-ja.com

nullで終了するconst char *のsizeof

const char* a;

文字列 'a'がnullで終了していることを確認するにはどうすればよいですか? a = "abcd"でsizeof(a)を実行すると、4が返されます。これは、nullで終了しないことを意味しますか?もしそうなら、私は5を獲得したでしょうか?

20
hari

Nullで終わるデータが含まれている場合と含まれていない場合があるchar配列を渡された場合、実際に確認する方法はありません。あなたができる最善のことは、(無制限ではない!)certianが指定した長さまでのnull文字を検索することです。しかし、0はメモリの初期化されていない領域で見つけるためのデータの異常なバイトではありません。

これは、多くの人々が嫌うCの事実上の文字列標準に関する多くのことの1つです。クライアントがあなたに渡す文字列の長さを見つけることは、せいぜいO(n)検索操作であり、最悪の場合でもセグメンテーション違反です。

もちろん、もう1つの問題は、配列とポインターが交換可能であることです。つまり、_array_name + 2_は&(array_name[2])と同じであり、sizeof(a)sizeof(char*)であり、配列の長さではありません。

5
T.E.D.

sizeof(a)は、ポインターが指す文字の配列ではなく、ポインターのサイズを示します。 sizeof(char*)と言ったのと同じです。

Nullで終了する文字列の長さを計算するには、strlen()を使用する必要があります(返される長さしないにはnullターミネータが含まれるため、strlen("abcd")は5ではなく4)。または、文字列リテラルで配列を初期化できます。

char a[] = "abcd";
size_t sizeof_a = sizeof(a); // sizeof_a is 5, because 'a' is an array not a pointer

文字列リテラル"abcd"はnullで終了します。すべての文字列リテラルはnullで終了します。

31
James McNellis

あなたは4は、システム上のポインタのサイズだからです。 nullで終了する文字列の長さを取得する場合は、C標準ライブラリのstrlen関数が必要です。

12
jer

ここでの問題は、コンパイル時の操作であるsizeof()と、実行時の操作である文字列の長さを混同していることです。 sizeof(a)を実行したときに4が返される理由は、aがポインターであり、Cのポインターのtypicalサイズが4バイトであるためです。文字列の長さを取得するには、strlenを使用します。

2番目の質問では、文字列がnullで終了していることを確認する方法。これを確実に行う唯一の方法は、自分で文字列をnullで終了することです。 char*のみを指定すると、適切にnullで終了することを100%保証する方法はありません。 char*のプロデューサーとコンシューマーの間の契約が、文字列を終了するユーザーについて確実に理解されるように、十分に注意する必要があります。

6
JaredPar

sizeof(a)は、ポインタのサイズであるsizeof(const char*)です。 aの内容には影響されません。そのためには、strlenが必要です。

また、ソースコード内の"abcd"などの二重引用符で囲まれた文字列リテラルはすべて、自動的にnullで終了します。

4
aschepler

sizeof(a)は_const char *a_...のサイズではなく、それが指しているサイズを返します。 strlen(a)を使用して、nullで終了する文字列の長さを調べることができます。strlenの結果には、null終止符は含まれていません。

1
semaj