0

マクロと文字列を連結して、ファイルへのパスを表す文字列を生成しています。関数は次のとおりです。

char *userPath(char *username)
{
   char *path = (char*)malloc(sizeof(char) * (strlen(MAILBOXES) + strlen(username) + 1));
   path[0] = '\0';
   strcat(path, MAILBOXES);
   strcat(path, "/");
   strcat(path, username);
   return path;
}

返されたポインターは正しい文字列を参照しますが、この関数を呼び出した後、プロセスは非常に悪い* glibc が検出されました./mmboxd: malloc(): メモリ破損: 0x085310a8 * * 相対バックトレース付き。このエラーを実装すると、このエラーが発生し始めたので、ここに問題があることを知っています。また、使用する唯一の malloc がここにあるためです。このコードの何が問題になっていますか?

4

8 に答える 8

9

+1 は、追加する区切り記号とヌル終端子を考慮して +2 にする必要があります。sizeof(char) は省略でき、常に 1 になります。

于 2011-04-28T18:11:47.657 に答える
4

問題は次のとおりです。

   char *path = (char*)malloc(sizeof(char) * (strlen(MAILBOXES) + strlen(username) + 1));

MAILBOXESa) のすべての文字、b) のすべての文字username、および c)文字に十分なメモリを割り当てて'/'いますが、d) 終了文字を忘れています'\0'! そう+ 1あるべき+ 2

コードには他にもいくつかの奇妙な点がありますが、それらは間違っているわけではなく、改善できる可能性があるだけです。

  1. の戻り値を C でキャストする必要はありませんmalloc。一部の (私のような) 人は、Google の能力を超えているというさまざまな理由から、スタイルが悪いと考えています。
  2. sizeof(char)常に 1 です (これは標準で定義されています)。一部の人々は、対称性のためにそれを維持すると言います. 1個なので外してくださいという人もいます。に変更すると、が適切なサイズを割り当て続けるように正しく調整されるようにsizeof *path、 に変更pathすると言う人もいます。wchar_t *malloc
  3. を使用strcatしてデータの最初のビットを文字列に書き込むと、非効率になる可能性があります。path[0] = '\0';行を削除してstrcpy、データの最初のビットに使用しないのはなぜですか?
  4. すべての文字列の長さを計算しますが、それらを捨てて を使用strcatすると、(以前に計算された) 長さを再トラバースして適切な場所を見つけます。strlen2 つの呼び出しの結果を保存した場合は、使用する必要がなくstrcat、文字列の末尾がどこにあるかを不必要に再計算し続ける必要はありません。
  5. を使用strcatして単一の文字を追加するのは非効率的です。
  6. malloc使用する前に、成功または失敗の戻り値を確認しません。
于 2011-04-28T18:18:54.943 に答える
2

ゼロターミネータ用のスペースが許可されていないようです。そのために余分に割り当てる必要がありますchar

はパスセパレーター用+1であると想定しています。malloc()それを作ると+2、終端のヌル文字のためのスペースができます.

于 2011-04-28T18:12:06.127 に答える
1

「パス」文字列を割り当てるときに、メールボックスとユーザー名の間に追加する「/」文字の長さを追加するのを忘れました。

于 2011-04-28T18:12:53.287 に答える
1

ゼロ終端のために別のバイトを malloc する必要があるようです。

于 2011-04-28T18:12:58.020 に答える
1

C 文字列の文字列ターミネータとして、ヌル文字 "\x00" に 1 バイト余分に割り当てる必要があります。

現在、/ 文字には余分なバイトを 1 つだけ割り当てます。

だから+1の代わりに+2を試してみてください

于 2011-04-28T18:13:15.427 に答える
1

終了ヌルのために char で予算を立てていません。malloc の長さは +1 ではなく +2 にする必要があります。

于 2011-04-28T18:13:23.763 に答える
1

のアカウント+1の終わりにあなた。ただし、最後にヌル文字用のスペースが必要です。これは、によって追加されます。だからそれはです。malloc()/strcat()+2

char *path = (char*)malloc(sizeof(char) * (strlen(MAILBOXES) + strlen(username) + 2));
于 2011-04-28T18:13:58.843 に答える