恥の20行

2009年4月5日·で掲示されるC / C + +オピニオン

米が調理されている間、私はC言語でメモリ管理を含む、初期の彼のキャリアの中で私に起こった奇妙な事件を思い出した+ +。 その当時、私はずっとあった。 、若いより速く、より多くの傲慢と多くの初心者...

より多くの経験豊富な同僚は、すべての新しいのために対応する削除がなければならないという別の経験の浅い同僚に説明していた そうでない場合はオブジェクトをメモリに保持され、メモリリークがあるかもしれません。

この時点で私は彼を中断して言った、"それは範囲外のオブジェクトはデストラクタが自動的に呼び出されるように十分なので、必ずしも.."

それ以来、引数とカウンターの引数での10分間の議論をロールバックし、チーム全体がまだ見て。 最後に、半分のチームは彼と私と残りの半分で合意し、その時点で誰もが心にかを確認する方法がありませんでした。 インターネット上で見てはオプションではなかった。

すべて既にPHP、JavaやCでプログラミングされた後私は、すべての答えを持っていたとして+ +私が正しかったことを後で示すことであった。

数日後、それらの哲学的な瞬間の一つは、私はメモリアドレスが数値であることを忘れて、そして後者は、通常は無用ですが、次のいずれか、共通の番号にアドレスを変換し、他の道を行くことができます。

それから私は私の理論を証明する方法を考案した:それは新しいの割り当てに制限範囲内のオブジェクトを作成します。 制限された範囲の長い外の一般的な数値としてこのオブジェクトのアドレスを保存する、制限された範囲を確定するために期待し、obejtoのデストラクタが呼び出され、その後、外側のスコープは、メモリのその領域にアクセスする、オブジェクトのアドレスを表す数値を使用してください受け取ることを示しているSIGSEGV無効なメモリ領域をアクセスしようとすることによって(セグメンテーションフォールト)。 それから私は、以下のコードを生成する。

  A
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
  #含める
 #<string>を含める

 名前空間 はstd  使用 

 int argc, char ** argv ) { int型です。main(int argc、char **は ARGV){
     0 ; = 0 符号なしの長い ;

     {
         new string ( "Hello World!!!" ) ; * strは= 新しい文字列("Hello World!"という);
         unsigned long ) str ; =(unsigned long型、str;

         "str: " << str << endl ; 裁判所 <<"STR:"<<str<<endlを。
         "num: " << num << endl ; 裁判所 <<"NUM:"<<A <<endlを。
     }

     * ( ( string * ) num ) << endl ; 裁判所 <<*((*文字列 )A)<<endlを。

     ; 0を 返します 
 } 

見よ、私の驚きへのプログラムは私の顔に爆発しなかった 彼は正しく、実際に私が間違っいた一人であることを指摘していました。

より多くの検索私は、はい、そこにそれぞれのために新しいものとのみ削除することを実現しより多くのそれぞれの新しいために[]いずれか1つだけが[]を削除する必要あります 私はメモリ管理と適用範囲について知ってどう思うか、それはおそらく、異なる言語の間にいくつかの混乱だった。

私は前に議論の一日を始めたとき、私は、初心者がコミットしているすべての基本的な間違いを犯した。

  1. それが呼び出された場所干渉する。
  2. 証拠なしに正しいことで立って悪態をついた。
  3. より多くの経験豊富な誰かの知識を過小評価しています。
  4. あなたは彼らが単にクラス内の参照といってすべての答えを持っていると思う。
  5. 彼らはいくつかの言語の基本を知っているという理由だけで、その後、すべての答えを持っていることを考えること。

種の任意の良いメンバーと同様にサピエンスホモ 、たわごとを話し。 この発見に私の反応は、チーム全体を取ると私が間違っていた、ナンセンスを話して謝罪し、これを実証するために使用されるコードのこれらの20行を示すことでした。 また、私は私がチェックし、さらに我々は同じように、エスケープされているメモリ管理に関するその他の詳細を持ってきたすべてのソースを示した循環参照を これは、プロジェクトの一部の再desingにつながった。

私の20行cógigoは"20恥の行"とnatual私は誤ったものなどとして知られるようになりました。 誰もが疑問を持っていたすべての時間は、"テストのためvegonhaの20行が存在する。"スポーク 意味は"後で困惑されないように簡単なテストがある。"のようなものだ

最も重要なことは、私の後のたわごとの姿勢がよく受信し、チームに利益をもたらしていたということです。 私は誰かが私は舞台裏で、皆の前で間違っている、または悪化した証明する、遅かれ早かれ、敬遠していた場合。 ミスを認めると、それから学ぶことは、私がチャレンジする準備されたことを示した。 このチームに加えて、より多くの私は(私は私より多くのように見える...),私はそれが皆のようなミスを犯して普通の人間のことを知っていた傲慢思えたが、私は誰よりも考えていないことを示した。 これは他のチームメンバーが同じことを気軽に、我々は、よりまとまりのあるチームになるための道を開いた。

コメント

  • マーカスアントニウス

    非常に興味深い話!
    議論をやった人々にとってはもっと荷物!

    別の興味深い点は、Ubuntuの新しいリリースの18日間の欠如です!
    (しかしそれは??????????時間が飛ぶ!)

  • http://blabos.org うっかり漏らす

    最近私はテレポーテーションのゴーイン、飛行していないtime'reのための...

  • Junio

    Blaberは、経験を通過してくれてありがとう。 非常にリッチテキスト。 あなたに平和と健康。

  • ♣♦♥♠姫チェシャー

    それは、オペレーティングシステム... C + +ディスプレイにより保護されていない限り、解放されたメモリをアクセスするときにうーん...私はあなたが使用したり、言語のどのバージョンがどのようなコンパイラはわからないが、私が知っている、Cはエラーを表示しないのですか?

  • ブレブのBlaber http://blabos.org

    訪問の最初の感謝!

    それは、C + + g + +が、小さいパダワンとなります :)

    それはあなたが"表示エラー"と考えるものに依存する。

    コンパイル時または実行時に?

    上記のケースでは、経験不足は(この不協和音!)破壊自動出力範囲と予想(動的に割り当てられたオブジェクトに存在しないC + +)、derreferenciaçãoによってエリア(以前に)解放されたメモリを指すポインタを続け、実行時に致命的なエラーを引き起こす。

    追加delete str; 14行目の後には微妙な違いが気付くでしょう。

    両方のテストでは、コンパイル時に警告を与えることはしないでください。

  • ♣♦♥♠姫チェシャー

    いやいや、私は同じランタイムで話す...最初は私がプログラミングを学習したとき、私たちの先生は、alloc、malloc関数とcallocの前に私たちにベクトルを教え、そのため、我々はメモリを割り当てることなく自由にベクトルを使用し...

    まれにメモリ保護されたオペレーティングシステムのエラーを明らかにしていない...
    また、何らかのエラーが表示される、またはコンパイルまたは実行されなかった。

    もちろん、それはオブジェクトではなかった、それは構造化プログラミングのクラスで、Cでだけだった...私はメモリをしない使用しようとすると私の質問ので... C + +では、アロケーションの代わりに、新しい使用して、プログラムは実行時にエラーを生成します。割り当てられて?

    私はそれは、すべての後に、デストラクタ言語の仕様を見ていいことだと思う、とメモリを解放すると、プログラムか何かが完了するまで、それを保護することができます...またはそれが発生しないのですか?

  • ブレブのBlaber http://blabos.org

    メモリアレイが存在する必要があるのに対して用語"我々はメモリを割り当てることなく自由に使用されるベクトルは"、非常に誤解を招くおそれがあります。 おそらくあなたは、"我々はベクトルが動的にメモリを割り当てることなく自由に使用する。"ことを意味

    仕様はほとんどのシステム(すべてではない)で致命的なエラーを意味する未定義の動作、にNULLポインタの結果derreferenciar言います。

    これは、上記示されているものではありません。 例では"伝えられるところで"割り当て解除された領域にアクセスしようとするとあります。

    ヌルポインタ!無効なメモリ領域に=のポインタ。


    int* ptr_null = 0;

    / /はヌルポインタptr_nullか

    ptr_foo =新しいint * int型(123456);
    ptr_fooを削除する。

    メモリ領域へ/ / Ptr_fooポイント
    もはやこのプログラムに属していない/ /こと

    のprintf("%PN"、ptr_null);
    のprintf("%PN"、ptr_foo);

    もし違いが表示されます例をコンパイルおよび実行します。

    最後の段落に関しては、ない、それは何が起こるかではありません。 あなたは物事を混合している、デストラクタは、オブジェクトがどちらかを呼び出すことによって、割り当てが解除されたときに自動的に呼び出されるルーチンですdeleteヒープ上に割り当てられたオブジェクトの出力または範囲で動的に割り当てられたオブジェクトを。

Disqusを搭載ブログのコメント