2017-09-27 3 views
-1

私は現在C言語を学習しており、文字列の2つの半分を入れ替える簡単な関数を作ることにしました。 strndmpを使用して文字列の半分を取得し、strncatを使用して残りの半分をstrndmp結果の末尾に追加しました。その後、私は出力を印刷しました。スクリプトは文字列の半分をスワップして出力しましたが、最後の数文字はランダムな文字に置き換えられました。私は本当に混乱しています。なぜなら、スワップされた文字列を印刷する前に何かを印刷したり、入力された文字列が24文字以下であれば、これは起こらないからです。ここでは、コードです:24文字を超えると、strncatまたはstrndmpがランダムな文字を追加します

#include <stdio.h> 
#include <string.h> 

void halfSwap(char * sample); 
void halfSwap(char * sample){ 
    char * buff; 
    buff = strndup(sample+strlen(sample)/2,strlen(sample)); 
    strncat(buff,sample,strlen(sample)/2); 
    printf("Sample length: %d\n",strlen(sample)); 
    printf("Buffer output: %s\n",buff); 
} 
int main() { 
    //printf("Uncommenting this will remove the error\n\n"); 
    //Characters only go missing after sample exceeds 24 chars 
    halfSwap(" worrrrrrrlddhellllllllooo"); 
    //Error does not occur after printng once 
    halfSwap(" worrrrrrrlddhellllllllooo"); 
} 

、出力は次のとおりです。事前に

Sample length: 26 
Buffer output: hellllllllooo worrrrrrrl 
Sample length: 26 
Buffer output: hellllllllooo worrrrrrrldd 

おかげで。

+0

あなたはそれを呼び出すたびに 'halfSwap()'にメモリをリークしています。 –

+1

AFAICS、['strndup()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/strndup.html)の仕様では、2番目の引数として多くのメモリを割り当てることは保証されていません。入力が第2引数よりも短い場合は、ヌルターミネータを含め、入力に十分なスペースしか割り当てられません。したがって、割り当てられた領域への追加は未定義の動作です。 [Valgrind](http://valgrind.org/)を実行できるプラットフォームを使用している場合は、それを使用してください。 –

+0

コードをデバッグして助けてくれれば(* code-blocks *などを使って)、おそらくあなた自身が答えを得るでしょう。さらに、変数とポインタの値をデバッグして検査することで、より速く学習するのに役立ちます。 – ssd

答えて

0

strndupを呼び出すと、文字列の後半に十分なメモリしか割り当てられないため、strncatを実行すると、buffに割り当てられた領域を超えて動作が定義されません。

int len = strlen(sample); 
int half = len/2; 
buff = (char*)malloc(len+1); 
strcpy(buff,&sample[half]); 
strncat(buff,sample,half); 
関連する問題