2016-08-08 7 views
-3

whileループ内に文字列を扱うループがforループ内にあります。ここでは基本的に私のコードの構造です:C言語でのfree()関数の問題

char myString[1000]; 
//Initialize and maybe change myString 
for(/*conditions*/){ 
    while(/*conditions*/){ 
     if(strchr(myString,' ') == NULL){ 
      break; 
     } 
     char *temp = malloc(sizeof(char) * strlen(myString)); 
     strcpy(temp,myString); 
     *strchr(temp,' ') = '\0'; 
     strcat(myString," "); 
     strcat(myString,temp); 
     free(temp); 
    } 
} 

時々、このコードはうまく動作しますが、時には、プロセスが終了し、3を返し、エラーがあることを意味している(3、私は通常、取得戻り値です私はNULLを使用しようとしています。たとえば、がNULLの場合はmyPointer->exampleです。いくつかのテストの後、問題の原因となった行がfree(temp);であることが分かりました。私はif(temp != NULL){free(temp);}と交換しようとしましたが、何も変わっていません。私はmallocの代わりにtempchar temp[1000]と宣言しようとしましたが、free(temp);行を取り除いていますが、それでも同じことがあります。 free(temp);行を取り除き、まだmallocを使用した場合、問題は解決されますが、代わりに膨大なメモリリークが発生するため、そのことはできません。エラーがあるかどうかは、myString文字列に何があるかによって決まります。つまり、ある値がある場合は常にエラーがあり、ある特定の値がある場合はエラーはありませんが、どのタイプの値が機能し、どのタイプの値が機能しないかを調べることができないため、ランダムであると思われます。

なぜfree(temp);が動作することがありますか、時には動作しない場合があります。どのようにして動作させることができますか?

+5

'char * temp = malloc(sizeof(char)* strlen(myString)); strcpy(temp、myString); '境界外の書き込み、未定義の動作です。また、 'strchr()'が 'NULL'を返すなら、' NULL'の逆参照のための未定義の振る舞いもあります。 – EOF

+0

また、 'sizeof(char)'は定義上1つで、 'malloc()'に渡される引数の一部として冗長です。 –

+0

この問題は、単純な入力ミスが原因で発生したため、この質問を閉じることにしました。 –

答えて

5

主な問題は、必要なメモリよりも少ない1つの要素を割り当てていることです。

strlen()は、終了nullを考慮していないため、必要なメモリが不足しています。その後、

strcpy(temp,myString); 

がバウンドアクセスのうち、実際にやってundefined behaviorを呼び出します(終端のヌルを格納します)。その結果、あなたは[...]

は時々、このコードはうまく動作しますが、時には、プロセスが終了し、3を返し、エラーがあることを意味して見ることが

あなたがman page

から、言っ

char *temp = malloc(strlen(myString) + 1); // +1 for terminating null, 
              // sizeof(char) == 1, guaranteed by C standard. 

のような割り当てステートメントを変更する必要があり、解決するために、文字が見つからない場合

strchr()strrchr()機能が一致した文字またはNULLへのポインタを返します。 [...]

と、そのヌル・ポインタ定数(NULL)参照解除に強調表示されたシナリオのために、

*strchr(temp,' ') = '\0';

試み無効であり、再びUBを呼び出す。返されたポインタを返す前に、有効な戻り値があるかどうかを確認してください。

+0

....そしてUBの場合、予期せぬ予期しない結果が生じる可能性があります。 – haccks

+0

@haccks右の先生、ちょうどこれを関連させるために質問から部分を引用しました。 :) –

+0

@DonaldDuck答えに編集をチェックしてください。問題が解決しない場合は、MCVEを作成してください。 –