30

私はそれstrdupが悪いと述べているいくつかのポスターを見てきました。これについてコンセンサスはありますか?malloc私は何の罪悪感もなくそれを使用しており、 /を使用するよりも悪い理由はわかりませんmemcpy

評判を得るかもしれないと私が考えることができる唯一のことstrdupは、呼び出し元がそれを悪用する可能性があることです (たとえば、返されたメモリを解放する必要があることに気付かない; strdup された文字列の最後まで strcat を試みます)。しかし、malloc された文字列も、誤用の可能性がないわけではありません。


質問が役に立たないと考えている人たちへの返信と謝罪に感謝します(投票は締め切ります)。strdup回答を要約すると、それ自体が悪である という一般的な感覚はないようですが、C の他の多くの部分と同様に、不適切または危険に使用される可能性があるという一般的なコンセンサスがあります。

「正しい」答えは実際にはありませんが、それを受け入れるために、@ nneoneoの答えを受け入れました-それは@ R ..の答えでもありました。

4

6 に答える 6

35

私が考えることができる2つの理由:

  1. 厳密にはANSICではなく、POSIXです。その結果、一部のコンパイラ(MSVCなど)は使用を推奨しません(MSVCが優先します_strdup)。技術的には、C標準は予約済みのプレフィックスであるためstrdup、異なるセマンティクスで独自に定義できます。strしたがって、その使用にはいくつかの潜在的な移植性の懸念があります。
  2. メモリ割り当てを非表示にします。他のほとんどのstr関数はメモリを割り当てないため、ユーザーは(あなたが言うように)返された文字列を解放する必要がないと誤解する可能性があります。

strdupただし、これらの点を除けば、コードの重複を減らし、一般的なイディオム(strdup("constant string")リテラル文字列の変更可能で戻り可能なコピーを取得するなど)の優れた実装を提供できるため、慎重に使用することは正当であると思います。

于 2012-10-20T03:25:15.327 に答える
21

私の答えはむしろサポートstrdupであり、Cの他の関数よりも悪くはありません。

  1. POSIXは標準でありstrdup、移植性が問題になった場合でも実装はそれほど難しくありません。

  2. strdup誰かがマニュアルページを読んでどのように機能するかを理解するのに少し時間がかかった場合、によって割り当てられたメモリを解放するかどうかは問題にはなりませんstrdup。関数がどのように機能するかを理解していない場合、その人が何かを台無しにする可能性が非常に高くなります。これは、だけでなく、すべての関数に適用できますstrdup

  3. Cでは、メモリやその他のほとんどのものはプログラマーによって管理されるため、strdupは、メモリの解放を忘れたり、文字列を nullで終了できなかったり、誤った形式の文字列を使用したり(および未定義の動作を呼び出したり)、ダングリングポインタにアクセスしたりするよりも悪いことではありません。 。mallocscanf

(私は本当にこれをコメントとして投稿したかったのですが、コメントを1つ追加できませんでした。したがって、回答として投稿しました)。

于 2012-10-20T23:24:06.517 に答える
10

私は実際strdupに悪として説明されているのを聞いたことがありませんが、一部の人々がそれを嫌ういくつかの考えられる理由:

  1. これは標準のCではありません(ただし、POSIXにあります)。ただし、この理由は、それがないシステムに追加するためのほぼ1行の関数であるため、ばかげていると思います。
  2. 可能な場合に文字列をインプレースで使用するのではなく、文字列をブラインドで複製すると、時間とメモリが無駄になり、コードに障害が発生する可能性があります。
  3. 文字列のコピーが必要な場合は、実際に文字列を変更または構築するためにより多くのスペースが必要になる可能性がありますが、それstrdupはできません。
于 2012-10-20T03:26:42.413 に答える
5

strdup に関する懸念の大部分は、バッファオーバーランと不適切なフォーマットの文字列に関するセキュリティ上の懸念から来ていると思います。null 以外で終了する文字列が strdup に渡されると、未定義の長さの文字列が割り当てられる可能性があります。これが具体的に攻撃に利用できるかどうかはわかりませんが、一般的には、ヌル文字だけに依存するのではなく、最大長を取る文字列関数のみを使用することが安全なコーディング プラクティスとして適切です。

于 2012-10-20T05:05:54.623 に答える
2

多くの人は明らかにそうではありませんが、個人的strdupにはいくつかの理由で悪を感じます。

  • 主なものは、割り当てを非表示にすることです。他のstr*関数やその他のほとんどの標準関数は、後処理を必要としないfreeため、無害に見え、その後のstrdupクリーンアップを忘れることができます。dmckee は、後でクリーンアップする必要がある機能のメンタル リストに追加することを提案しましたが、なぜですか? 2 つの中程度の長さの行を 1 つの短い行に減らすことに大きな利点はないと思います。

  • 常にヒープにメモリを割り当てます.C99(99ですか?)のVLAを使用すると、使用するもう1つの理由がありますstrcpy(必要さえありませんmalloc)。いつもできるとは限りませんが、できるときはそうすべきです。

  • これは ISO 標準の一部ではありません (ただし、POSIX 標準の一部です。Wiz に感謝します)、R.. が簡単に追加できると述べたので、それは本当に小さな点です。移植可能なプログラムを作成する場合、それが既に定義されているかどうかをどのように判断するかはわかりません...

もちろん、これらは私自身の理由のいくつかであり、他の誰の理由でもありません。あなたの質問に答えるために、私が知っているコンセンサスはありません。

あなたが自分のためだけにプログラムを書いていてstrdup、問題がないと思うなら、それを使わない理由は、スキルレベルや年齢の異なる多くの人に読まれるプログラムを書いている場合よりもはるかに少なくなります。

于 2012-10-20T04:13:39.900 に答える
1

言及されていない strdup が嫌いな理由は、自然なペアのないリソース割り当てだからです。ばかげたゲームを試してみましょう: 私が言うmalloc、あなたが言うfree. 私はあなたが言うと言いopenますclose。私はあなたが言うと言いcreateますdestroy。私はstrdupあなたが言うと言います....?

実際、答えstrdupはもちろんであり、それを明確にするためにfree関数に名前を付けたほうがよいでしょう。malloc_and_strcpyしかし、多くの C プログラマーはそれをそのように考えておらず、解放strdupするためにその反対または「終了」が必要であることを忘れています。free

私の経験では、 を呼び出すコードでメモリ リークが見つかることは非常に一般的strdupです。strlen、 、mallocを組み合わせた奇妙な関数strcpyです。

于 2016-05-30T03:55:28.877 に答える