私は任意の長さの文字列を作成し、すべての文字を特定の文字に設定する必要があるプロジェクトに取り組んでいます。バイトを設定するmemsetで手動でバイトを設定すると文字列が短くなるのはなぜですか?
例:
char str[i];
memset(str, '*', i);
str[i] = '\0';
これは、これまで動作しているようです、しかし私はstr[i + 1] = '\0';
に最後の行を変更すると、私の出力が1に短縮されています。
これはなぜ起こっているのですか?
私は任意の長さの文字列を作成し、すべての文字を特定の文字に設定する必要があるプロジェクトに取り組んでいます。バイトを設定するmemsetで手動でバイトを設定すると文字列が短くなるのはなぜですか?
例:
char str[i];
memset(str, '*', i);
str[i] = '\0';
これは、これまで動作しているようです、しかし私はstr[i + 1] = '\0';
に最後の行を変更すると、私の出力が1に短縮されています。
これはなぜ起こっているのですか?
str[i] = '\0';
と
str[i + 1] = '\0';
C言語は配列境界をチェックしていないため、未定義の動作です。
C11標準:
J.2不定behavor
- 配列の添字は、オブジェクトが左辺値のように(与えられた添え字と明らかにアクセス可能であっても、範囲外であります式 a [1] [7]宣言int a [4] [5])(6.5.6)を指定します。
はstr[i]
とstr[i + 1]
を使用すると、str
の境界外にアクセスされています。これはundefined behaviourです。
データの長さ(終端ヌルバイトを除く)がi
である必要がある場合、ヌルターミネータに対応するために、配列str
にはi + 1
要素のスペースが必要です。
一方、str
をC文字列として使用していない場合(たとえば、NULL終了文字列が必要な標準Cライブラリ関数のいずれかを使用している場合)、NULLを終了する必要はありませんすべて。
'str [i + 1]'は境界にありません。 'str [i]'もそうではありません。あなたは '0'から' i - 1'までのインデックスを持つ 'i'要素を配列として宣言しました。 – Ryan
[mcve]を入力してください。 – rustyx
'int i = 42;を実行することに注意してください。 char str [i]; 'は可変長配列と呼ばれる言語要素を利用します。これはC99のみで利用可能であり、C11では* optional *になっています。 (また、VLAはC++では全くサポートされていません)、 – alk