次のコードでは、文字列をchar * strにコピーします。長さは10文字で、strncpy()
を使用しています。文字列はNULLで終了しませんが、それでも正常に動作します、なぜですか?
strncpy()
マニュアルによると、 "警告:srcの最初のnバイトの間にヌルバイトがない場合、destに配置された文字列はnullで終了しません"。
ソース文字列の長さが26文字で、10文字をコピーしているため、NULL文字はstrの最後に配置されません。
しかし、私が '\ 0'を得るまで、0から始まるstrの内容を出力するとき、それは正常に動作します。
なぜですか?最後に '\ 0'がない場合、ループはなぜ正しい場所に停止しますか?
私が理解しているのは、「セグメンテーションフォールト」を与えなければならないということです。少なくとも、そこで停止してゴミ値を残してはいけません。ここで
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 10
int main()
{
char *str ;
str = malloc(sizeof(char) * SIZE);
if(str == NULL)
exit(1);
memset(str, 0, sizeof(char) * SIZE);
strncpy(str, "abcdefghijklmnopqrstuvwxyz", sizeof(char) * SIZE);
unsigned int index;
for(index = 0; str[ index ] != '\0' ; index++) {
printf("str[ %u ] has got : %c \n ", index, str[ index ]);
}
return 0;
}
が出力されます。
str[ 0 ] has got : a str[ 1 ] has got : b str[ 2 ] has got : c str[ 3 ] has got : d str[ 4 ] has got : e str[ 5 ] has got : f str[ 6 ] has got : g str[ 7 ] has got : h str[ 8 ] has got : i str[ 9 ] has got : j
任意の助けが理解されるであろう。
EDIT
は、文字列は「\ 0」かで終わるかどうかを確認するための適切な方法はありますか?私はいつも上記のループが究極のテストであると考えましたが、今はそうではないようです。
他のプログラマーが開発した関数から文字列を取得するとします。今、「\ 0」で正しい場所で終わることをどのように知るでしょうか。そうでないかもしれませんが、それは実際のサイズを超えて、いくらかの '\ 0'が得られるまでです。文字列の実際のサイズは決してわかりません。
どのようにこのような状況に取り組んでいますか?
提案がありますか?
sizeof(char)is * always * 1 !! – paxdiablo
@Pax:それでも、それについての議論があります:http://stackoverflow.com/questions/1011806/is-it-necessary-to-multiply-by-sizeof-char-when-manipulating-memory – sharptooth
strncmpはしかし文字列のサイズではないので、そこで使うのは間違いです。 –