4

とても面白い質問を見つけました。

次のコードを使用している場合:

int main() {
    char * in = "hi, ";
    char str[10];
    strncpy(str, in, 2);
    printf("output = %s", str);
    return 0;
}

私の結果は何もありません、printfうまくいきませんでした。

しかし、私がこれを使用する場合:

int main() {
    char * in = "hi, ";
    char * str = malloc(sizeof(char) * 10) ;
    strncpy(str, in, 2);
    printf("output = %s", str);
    return 0;
}

期待通りの結果が得られます。

なぜこれが起こるのですか?スタックとヒープのせいですか?それはどのくらい正確にこの大きな違いを生むのでしょうか?

4

3 に答える 3

6

問題は、どちらの場合も、への呼び出し後に文字列が適切に終了しないことstrncpyです。

文字をコピーするように指定し2、ソース文字列inの長さを4strncpyにします。2文字をコピーします。これはソース文字列の長さよりも短いため、nullターミネータは追加されません。これがなぜそうなのかを理解するには、次を確認してください。 strncpyのドキュメント:

If count is reached before the entire string src was copied, the resulting character array is not null-terminated.

この場合、次のことが必要になります。

str[2] = '\0';

'strncpy'の後。

2番目のケースは、取得したバッファーがたまたますべてゼロに初期化されているために機能しているように見えるかもしれませんがこれに依存するべきではありません。malloc

strncpyのドキュメントを確認し、null終了の例外に注意してください。一般に、文字列の終了には注意してください。

詳細については、次を参照してください。C++の文字列が通常「\0」で終了するのはなぜですか。

于 2012-06-11T20:54:59.343 に答える
5

コードは正常にコンパイルされます。str実行時エラーは、nullで終了していないことが原因である可能性があります。

マニュアルページから:

strncpy()関数は、最大nバイトのsrcがコピーされることを除いて同様です。警告:srcの最初のnバイトの中にnullバイトがない場合、destに配置された文字列はnullで終了しません。

str[2]=0;の後に追加しstrncpy()ます。

于 2012-06-11T20:55:10.310 に答える
1

ゼロを使​​用してメモリを初期化すると、「安全」な側になります。

次のコードを見てください、

int main() {
    char * in = "hi, ";
    char str[10]={0};    
    strncpy(str, in, 2);
    printf("output = %s", str);
    return 0;
}

int main() {
    char * in = "hi, ";
    char * str = calloc(10,sizeof(char));
    strncpy(str, in, 2);
    printf("output = %s", str);
    free(str);      //<<Important step
    return 0;
}

str[2] = '\0';も有効な解決策です。

于 2012-06-12T04:51:32.777 に答える