web-dev-qa-db-ja.com

printf( "%s"、char *)はいつ印刷を停止しますか?

私のクラスでは、Cのmalloc()関数の独自のコピーを作成しています。私のコード(現在スペースをうまく割り当てることができる)をテストするために、私は使用していました:

_char* ptr = my_malloc(6*sizeof(char));
memcpy(ptr, "Hello\n", 6*sizeof(char));
printf("%s", ptr);
_

通常、出力は次のようになります。

_Hello
Unprintable character
_

Ptrのメモリは次のとおりであるため、一部のデバッグでは、コード自体がこれを引き起こしていないことがわかりました。

[24バイトのメタ情報] [要求されたバイト数] [パディング]

それで、printfがパディングに到達していることがわかりました。これは単なるゴミです。そこで、次のテストを実行しました:printf("%s", "test\nd");そして得た:

_test
d
_

Printf( "%s"、char *)がcharの印刷を停止するのはいつですか?

15
user327406

ヌル文字(\0)、なぜなら%sは、文字列がnullで終了することを期待します(つまり、引数がC文字列であることを期待します)。

文字列リテラル"test\nd"はヌル終了です(すべての文字列リテラルはヌル終了です)。ただし、文字配列ptrは、バッファに6文字しかコピーしないため(Hello\n)、7番目の文字(ヌルターミネータ)をコピーしません。

29
James McNellis

Jamesは、printfがnull文字に達したときに停止することについて正しいです。また、Uriは、「hello\n」を保持するために7文字のバッファーを割り当てる必要があることについて正しいです。

文字列のコピーに通常のCイディオムを使用すると、ターミネータとの混乱が緩和されます。memcpyではなくstrcpy(ptr, "Hello\n")です。

また、定義上、Cではsizeof(char)== 1であるため、6*sizeof(char)は冗長です。

5
David Gelhar

C文字列はnullで終了します(最後に\ 0文字があります)。これにより、Cは、印刷を停止したり、バッファを文字列として処理したりするタイミングを認識します。割り当てたスペースよりも長いスペースに文字列を配置しないのはあなたの責任です。

Hello\nは6文字の文字列ではなく、実際には7文字の文字列であることに注意してください。 Helloに5つ、改行に1つ、ヌルターミネータに1つを使用します。

7文字を6文字のバッファに収めようとするとバグと見なされます。現在発生している問題の原因かどうかはわかりませんが、6文字をコピーしてもヌルターミネータはコピーされないようです。だから私は実際にあなたのプリントがハローを超えて実際のジャンクになることを期待しています。

3
Uri

ゼロに達したとき。 7文字必要です。

0
Sanjay Manohar