strdup
は悪だと言っているポスターを見たことがあります。これについてコンセンサスはありますか?私は何の罪悪感もなく使用しましたが、malloc
/memcpy
を使用するよりも悪い理由はありません。
strdup
の評判は、呼び出し元が誤用する可能性がある(たとえば、返されたメモリを解放する必要があることに気付かない、strdupされた文字列の最後までstrcatを試行する)と私が思う唯一のことです。しかし、mallocされた文字列には、誤用の可能性もありません。
質問が役に立たないと見なした人への返信と謝罪に感謝します(投票への投票)。返答を要約すると、strdup
自体は悪であるという一般的な感覚はないようですが、Cの他の多くの部分と同様に、不適切または危険に使用できるという一般的なコンセンサスがあります。
「正しい」答えは実際にはありませんが、それを受け入れるために、私は@nneoneoの答えを受け入れました。
私が考えることができる2つの理由:
_strdup
_を優先します)。技術的にstrdup
は予約済みのプレフィックスであるため、C標準は独自のstr
を異なるセマンティクスで定義できます。そのため、その使用にはいくつかの潜在的な移植性の懸念があります。str
関数はメモリを割り当てないため、返された文字列を解放する必要がないとユーザーが誤解している可能性があります。しかし、これらの点は別として、コードの重複を減らし、一般的なイディオム(strdup("constant string")
など)の素敵な実装を提供して、可変で返却可能なコピーを取得できるので、strdup
の慎重な使用は正当化されると思いますリテラル文字列)。
私の答えはむしろstrdup
をサポートしており、Cの他の関数よりも悪くはありません。
POSIXは標準であり、移植性が問題になる場合、strdup
の実装はそれほど難しくありません。
strdup
によって割り当てられたメモリを解放するかどうかは、manページを読んでstrdup
がどのように機能するかを理解するのに少し時間を費やした場合には問題になりません。関数がどのように機能するかを理解していない場合、人が何かを台無しにしようとしている可能性が高く、これはstrdup
だけでなくany関数にも当てはまります。
Cでは、メモリと他のほとんどのものはプログラマーによって管理されるので、strdupはfreemalloc
edされたメモリを忘れてnull terminateに失敗するよりも悪いことではありません=文字列、scanf
で不正なフォーマット文字列を使用(および未定義の動作を呼び出す)、アクセスダングリングポインタなど.
(私は本当にこれをコメントとして投稿したかったのですが、1つのコメントを追加できませんでした。そのため、回答として投稿しました)。
strdup
が悪だと説明されているのは聞いたことがありませんが、一部の人々がそれを嫌ういくつかの考えられる理由:
strdup
はそれを提供しません。Strdupに関する懸念の大部分は、バッファオーバーランに関するセキュリティの懸念、および不適切にフォーマットされた文字列に起因していると思います。 null以外で終了する文字列がstrdupに渡されると、未定義の長さの文字列を割り当てることができます。これが攻撃に具体的に利用できるかどうかはわかりませんが、一般的には、ヌル文字だけに依存するのではなく、最大長を取る文字列関数のみを使用するのが安全なコーディング方法です。
多くの人は明らかにそうしませんが、私はいくつかの理由でstrdup
を個人的に悪と感じています、
主なものはそれが割り当てを隠すことです。その他str*
関数と他のほとんどの標準関数は、後でfree
を必要としないため、strdup
は無害に見え、その後のクリーンアップを忘れることがあります。 dmckeeは、後でクリーンアップする必要がある関数のメンタルリストに追加することを提案しましたが、なぜですか? 2本の中くらいの長さの行を1本の短い行に減らすことに比べて大きな利点はないと思います。
それは常にヒープにメモリを割り当て、C99(それは99ですか)のVLAでは、strcpy
を使用するもう1つの理由があります(malloc
も必要ありません)。いつもこれができるわけではありませんが、できる場合はそうするべきです。
これはISO標準の一部ではありません(ただし、POSIX標準の一部です。Wizのおかげです)が、R ..が簡単に追加できると述べたように、これは本当に小さな点です。あなたが移植可能なプログラムを書いているのなら、それがすでに定義されているかどうかをどのように伝えるかはわかりません...
これらはもちろん、私自身の理由のいくつかであり、他の理由ではありません。あなたの質問に答えるために、私が知っているコンセンサスはありません。
自分だけのプログラムを作成していて、strdup
に問題がないことがわかった場合、それを使用しない理由は、多くのスキルレベルと年齢の多くの人に読まれるプログラムを作成している場合よりもはるかに少なくなります。
言及されていないstrdupを嫌う私の理由は、自然なペアのないリソース割り当てであるためです。ばかげたゲームを試してみましょう。私はmalloc
と言い、あなたはfree
と言います。私はopen
と言い、あなたはclose
と言います。私はcreate
と言い、あなたはdestroy
と言います。私はstrdup
と言います....?
実際、strdup
の答えはもちろんfree
であり、関数の名前はmalloc_and_strcpy
それを明確にするため。しかし、多くのCプログラマーはそれをそのように考えておらず、strdup
は割り当てを解除するためにfree
の反対または「終了」が必要であることを忘れています。
私の経験では、strdup
を呼び出すコードでメモリリークを見つけることは非常に一般的です。 strlen
、malloc
、strcpy
を組み合わせた奇妙な関数です。