20行的恥辱

2009年4月5日發布的C / C + +意見

而大米做飯,我想起了一個奇怪的情況發生在我身上,在他的職業生涯的早期,涉及內存管理的C + +。 當時我得多。 年輕,速度更快,更加囂張,更多的新手...

一個更有經驗的同事解釋到另一個經驗不足的同事,為每一個新的,必須有相應的刪除。 否則對象將堅持在內存中,有可能是內存洩漏。

在這一點上,我打斷他說:“不一定,因為它是足夠的,對象的範圍,所以析構函數被自動調用。”

從那時起推出一個論點和反駁的10分鐘的辯論,和整個團隊的駐足圍觀。 一半的球隊在最後,同意和他一起與我的另一半,在這一點上,沒有人在頭腦裡的方式進行檢查,看。 看看在互聯網上是不是一種選擇。

正如我有所有的答案,因為我已​​經在PHP,Java和C編程+ +是後來證明我是正確的。

以後的日子裡,這些哲學的時刻之一,我記得一個內存地址是一個數字,你可以轉換地址到一個共同的數目,走另一條路,雖然第二個選項通常是毫無意義的。

然後,我想出了一個方法來證明我的理論:它會創建一個對象分配新的禁區範圍。 我會保持為1 1禁區範圍的長出來的共同數量這個對象的地址,期望來完成的限制範圍,在obejto的析構函數被調用和然後外部範圍,將使用對象的地址的數字來訪問該內存區域顯示收到SIGSEGV的試圖訪問無效的內存區域(分割錯誤)。 然後,我生成下面的代碼。

 
 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(INT ARGC的char ** argv的){
     0 ; 無符號長= 0;

     {
         new string ( "Hello World!!!" ) ; * STR =新的String(“你好,世界!”);
         unsigned long ) str ; NUM =(無符號長),STR;

         "str: " << str << endl ; cout <<“請STR:”<< STR << endl;
         "num: " << num << endl ; cout <<“請民:”<<一個<< endl;
     }

     * ( ( string * ) num ) << endl ; COUT << *((*字符串))<< endl;

     ; 返回0;
 } 

看哪,我吃驚的是,方案沒有在我的臉上爆炸。 他曾正確地顯示,其實我是一個人是錯誤的。

尋找更我意識到,應該是每一個新的,只能刪除,並為每個新的[]必須是一個只有一個刪除[]。 什麼,我想我知道內存管理和範圍,它可能是一些不同的語言之間的混淆。

當我開始討論天前,我做了所有的新手犯的基本錯誤:

  1. 染指的地方,它被稱為。
  2. 宣誓站在什麼是正確的,沒有任何證據。
  3. 低估了人的知識,經驗更豐富。
  4. 我想你知道所有的答案,只是因為你只看到它在課堂上。
  5. 認為,僅僅因為他們知道幾種語言的基礎知識,使所有的答案。

如任何成員智人的物種,談狗屎。 這一發現,我的反應是整個團隊,我錯了,胡說八道道歉,並顯示這些代碼二十行,我用它來證明這一點。 此外,我表明,我研究了所有來源,甚至提出了有關內存管理的其他細節,我們都喜歡逃避, 循環引用 這導致了該項目的某些部分重新德興。

我的20條線cógigo成為“20行的恥辱”,並natualmente我是如此擰。 任何人有任何疑問每次發言:“有20的vegonha線測試。” 類似“的意思是,有一個簡單的測試,不尷尬。”

最重要的是我的後拉屎的態度,深受歡迎,並給球隊帶來了好處。 如果我避開早晚有人會證明我是錯的幕後,前面的每一個人,或者更糟。 承認錯誤,並從中吸取教訓,我準備接受挑戰。 在這支球隊除了表明,我似乎囂張(我喜歡比我更期待...),我知道這是一個普通的人,他犯了一個錯誤,因為任何人,我不認為比任何人都。 這鋪平了道路,為其他團隊成員隨時做同樣的,我們成為一個更具凝聚力的團隊。

評論

  • 馬庫斯·安東尼

    非常有趣的故事!
    那些跟著辯論行李!

    另一個有趣的事情是缺乏Ubuntu的新版本的18天!
    (可是現在呢???時間過得真快!)

  • http://blabos.org blabos

    最近,我time're不飛,隱形傳輸布萊恩...

  • junio

    blabos,感謝您傳遞經驗。 非常豐富的文本。 和平與健康。

  • ♣♦♥♠柴姬

    嗯......我不知道用什麼編譯器,你什麼樣的語言版本,但我知道,C並沒有顯示錯誤,當訪問釋放的內存,除非它是由操作系統保護... C + +的顯示器嗎?

  • http://blabos.org Blabos的Blebe

    首先感謝您訪問!

    是C + +與g + +中,小學徒 :)

    取決於你考慮“顯示錯誤”。

    在編譯時或運行時?

    在上述情況下,缺乏經驗預計(噪雜這銷毀自動輸出範圍(C + +中動態分配的對象),由derreferenciação一個指針指向一個地區(以前)釋放的內存不存在!) ,導致在運行時的致命錯誤。

    添加delete str;第14行後,你會發現細微的差別。

    這兩項測試在編譯時不給任何警告。

  • ♣♦♥♠柴姬

    不,不,我說在同一個運行時...在開始時,我正在學習方案,我們的老師教我們之前的alloc,malloc和calloc載體,因此,我們沒有分配內存使用向量自由...

    很少了錯誤的內存受保護的操作系統...
    此外,沒有任何錯誤出現,或在編譯或執行。

    當然這是與對象不與C結構化編程的類,...所以我的問題......在ç+ +使用,而不是對ALLOC新,程序生成在運行時的錯誤,如果我嘗試到使用內存不如何分配?

    我認為這將是很好看到了語言的規範,畢竟,析構函數,釋放內存,可以保護,直到他們完成的程序或東西......或者它不會發生呢?

  • http://blabos.org Blabos的Blebe

    術語“載體,我們不分配內存的情況下自由地使用”是相當誤導,為存儲器陣列需要存在。 也許你的意思是“我們使用無向量動態分配內存的自由。”

    規範說derreferenciar空指針的結果在不確定的行為,這在大多數系統中(但不是全部),是指一個致命的錯誤。

    這是不是上面所顯示的。 在這個例子中,有試圖訪問一個地區的假想“釋放。

    空指針!=無效的內存區域的指針。


    int* ptr_null = 0;

    / /是一個空指針ptr_null的

    ptr_foo INT * =新的int(123456);
    刪除ptr_foo;

    / / Ptr_foo的內存區域
    / /不再屬於這個節目

    輸出(“%PN”ptr_null),;
    輸出(“%PN”ptr_foo),;

    編譯和運行的例子,你會看到其中的差別。

    至於最後一段,不,這是沒有發生什麼變化。 你混事,析構函數僅僅是一個被稱為自動釋放對象時,可以通過調用例程delete動態分配的對象,對輸出或者在堆棧上分配的對象的範圍。

博客評論由Disqus