2009-07-07 13 views
10

私はBjarne Stroustrupのフレーズをたくさん聞いたことがあります。"C++は足で自分を撃つのが難しくなりますが、そうすると足全体が離れる"と私はそれが本当にわからないそれは恐ろしいほどです。C++の最も危険な機能は何ですか?

C++でプログラミングしている最中に、あなたのソフトウェアに(あるいはもっと適切に)起こった最悪のことは何ですか?どのようにして、プレーンCというよりも危険なことがありますか?

+3

あなたが行っていることを認識するたびに、危険はありません。猿の手の中の銃はいつもトラブルにつながります。 –

+3

ええ、バナナの方がずっと少ないです。 –

+0

私はあなたに答えはしませんが、私はこれまで話題で聞いたことのある最も記憶に残ったアドバイスをお伝えします。つまり、「例外を逃すのを忘れた場合、アプリケーション全体が終了します!」なんらかの理由で、その時私にはかなり不愉快に聞こえました。 –

答えて

11
delete [] array; 

は時々知らない誰かの手の中に

delete array; 

になることができます。そのバグを追跡することは恐ろしいことになる可能性があり、あなたがmallocをやっているときには起こりません。

+1

あなたが知っているように、配列や単一の項目を区別しないので、mallocではそれが起こりません。 – Skurmedel

+1

正確です。だから私はそこにある 'のように見える'句を取り除いた。 – mmr

+0

Hehe same here :) – Skurmedel

1

例外処理の実装は、メモリリークの容易なinroadです。

+0

どのように?参照の代わりにポインタによってスローされた例外の場合を考えていますか? –

+2

適切なRAIIでは、これは問題ではない、と私は思う。 –

+0

同意しない。メモリが例外でリークする理由はありません。例外がどのように宣言されているかは、標準が非常に明確です。 –

0

Cには存在しないC++の最も危険な側面であることも理由です。例えば、減算を加えることは非常に簡単です(逆もまた同様です)。

だれでもだれでもをすればすることができますが、できます。危険なものにする。

4

仮想デストラクタの要件は、新しい方が見逃しやすい(私はほとんどのコンパイラがこれを指摘するのに十分スマートだとは思うが)。

+0

どのような仮想デストラクタ要件? – ralphtheninja

+0

@Magnus:ベース(または祖先)へのポインタを介してオブジェクトを破壊すると、デストラクタが仮想でない場合、間違ったデストラクタが呼び出されます。したがって、オーバーライドされるように設計されたクラスはおそらく仮想デストラクタを持つべきです。 –

2

Operator overloading。何が起こっているのかを理解することが非常に簡単です。経験豊富なC++開発者であっても、過負荷が起こっているという事実を見落とすのは簡単です。

+7

オーバーロードされた演算子がその役割を果たします。私はこの機能が本質的に悪いとは言っていません。それは、人々が困難を直感的に反撃するように定義することから始まります。オーバーロードされた演算子は、適切に使用されると、コードをよりシンプルかつクリーンにすることができます。 –

0

C++とCの安全性を比較しようとするなら、あなたはその言葉の要点を見逃しています。おそらくC++はC言語より安全ではありません。

本当に比較できるのは、Javaなどの言語です。本質的に、Javaはあなたのためにあなたのメモリを扱うので、あなたのプログラムが現在使っているメモリの外でメモリを呼び出すときには未定義の動作に終わらないでしょう(配列の境界を越えるなど)。

あなたの質問に対処するために、私に起こった最悪の事は自分自身のパスワードを上書きするバッファオーバーフローでした(私は意図的にそれをやった)。

+0

非常に真です。 C++の最も危険な側面は、実際にCからのホールドオーバーです.C++には、Cには存在しないいくつかの機能があります(演算子のオーバーロードなど)。私は質問がそれらについて尋ねていると信じています。 – Randolpho

+0

静的型チェックは、C言語よりC++よりも厳密に強制することができます。(typedefは最後に "anything goes"のようなものがあります) – fortran

+2

C++はあなたに選択肢を与えます。 –

0

私はいつもその引用について不思議でした。私はC++がどのような場合にはC.

よりより危険である任意の方法を考えることはできません、私が最も危険な「機能」が割り当てられていないメモリにアクセスするからあなたを停止するには何もないということであると言っています。デバッグがほとんど不可能で、あらゆる種類のランダムな動作がクラッシュから何も起こらず、奇妙な動作に変わるエラーです。

2

私はこのをコンストラクタの別のオブジェクトのヘルパー関数に渡しました。ヘルパー関数は、ポインタを維持していたオブジェクトのリストに追加しました。もちろん、コンストラクタが終了して返された後、オブジェクトはメモリ内の非常に異なる場所に配置され、他のオブジェクトに格納されたポインタはもはや有効ではありませんでした。 Yikes!

+0

それは本当ですか? : - | – fortran

+2

"this"をコンストラクタから漏らすことは決して安全ではありません。特に、マルチスレッド環境ではなく、オブジェクトが部分的に構築されているか部分的にしか見えない場合があります。コンストラクタが返されるまでオブジェクトは完全に構築されていると仮定することはできません(これはJavaとC#でも当てはまります)。 –

+0

あなたはバグがあったようです。 –

0
  • 演算子オーバーロードを正しく(誤用に簡単に)
  • 多重継承、私が持っているでしょう
  • バッファオーバーフロー
2

を実装していない場合は自動型変換を言います。 C++では、自動型変換により、直感的ではない方法で一時変数を作成できます。

関連する問題