2017-01-25 3 views
0

C標準に従って文字列が重なり合っていますか? C規格から

7.21.2.4はstrncpy関数

コピーが重なるオブジェクト間で行われる場合、動作は未定義です。重複している何


宛先文字列の先頭がソース文字列の終わりを横切るときに重複していることは明らかです。

しかし、次の例では重複していますか?

const char* dateConst = "2017-01-25"; 
char* date = malloc(16); 
strcpy(date, dateConst); 

strncpy(date+4, date+5, 2); 
strncpy(date+6, date+8, 3); 

printf("%s\n", date); 

出力:20170125

のstrncpyはちょうどそれがthis implementationであるようにcharでchar型のシンボルをcopyes場合、問題はないはずです。

+1

C標準では 'strncpy'の動作を規定していますが、C++をコンパイルしているようです。 – StoryTeller

+0

' strncpy'は危険な機能であり、避けるべきです。これは、nullで終了する文字列ではじめて使用することは意図されていませんでした。代わりに、 'memcpy'または' strcpy'を使用してください。 – Lundin

答えて

1

strncpyがこの の実装のように、charをcharでコピーするだけで問題はありません。

これはまさに問題です。 標準では、関数がどのように動作しなければならないかを指定していませんが、どの出力を与えるべきかを指定します。また、重複があった場合、結果はUBです。好き。

これは、新しい命令またはプロセッサアーキテクチャが、異なるアドレシング方法(すなわち、逆の順序または混在した順序でコピー)に従うことができる、より効率的で新しい命令の使用を後援することができるからです。これにより、予測できない結果が得られます。実際には、未定義の動作です。

最終的には、重複を明示的に許可する機能、または重複を認識する独自の関数を書き込むことができます。memmove

1

strncpyは、特定の方法で実装する必要はありません。 C標準は、それに従うべきAPI契約を指示するだけです。すべて特定の実装では、オーバーラップを問題にならないようにすることができますが、標準によって強制されるわけではありません。

strncpyは、memcpyで実装することができます。これは、送信元と宛先が重複した場合に未定義の動作が発生する可能性があります。しかし、上記の仕様では、それは完全に大丈夫です。

+0

'memcpy'は重複を許さず、' memove'は重複を許します。あなたは答えを修正したいかもしれません。 –

+0

@Frankie_C - 私は私が言ったことを意味して以来、私は何を意味した。 'strncpy'はオーバーラップすると未定義の振る舞いを持つことができるので、**可能なライブラリ実装では' memcpy'を使うことができます。 – StoryTeller

+0

申し訳ありませんが私は誤解しています。同意するなら、私はすべてのコメントを削除します。 –

関連する問題