Lab 2-3: Memory Leakage Detection

   
實習目標

1. 練習在 Visual Studio 2010 中運用 crtdbg 函式庫偵測記憶體未釋放的錯誤 (Visual Studio 2005/2008)

2. other tools: Valgrind example

   
步驟一 下列程式片段中有記憶體未釋放的錯誤:
    struct File
    {
        char *name;
        char *data;
    } *filePtr;
    ...
    filePtr = (struct File *) malloc(sizeof(struct File));
    filePtr->name = (char *) malloc(20*sizeof(char));
    filePtr->data = (char *) malloc(500*sizeof(char));
    ...
    free(filePtr);
上面這個程式片段中配置給 name 和 data 的 520 個位元組並沒有釋放, 只釋放了配置給 struct File 結構的記憶體。
程式裡有這種錯誤會導致什麼現象? 微軟早期的視窗系統中系統執行幾天以後就會出現 "系統資源不足", 不穩定當機的現象, 有的時候你用你的手機也會發現不太穩定需要重開, 常常就是作業系統裡面的程式或是所執行的應用程式裡有這種記憶體 未釋放的錯誤, 程式如果只執行幾分鐘或是幾個小時還不會發生什麼問題, 可是一旦像你的手機上的程式長時間執行就穿幫了。
步驟二 下面幾個執行程式都有類似的錯誤, 常常在單獨測試時看不到錯誤, 當撰寫的程式很大時, 要找到究竟在什麼地方發生這種錯誤其實有相當的困難度: C/C++ 語言希望給程式撰寫者最大的操作彈性, 演算法裡面所使用的記憶體的配置釋放完全由程式設計者來控制, 因此寫程式的人必須徹底了解到 "程式配置多少個位元組的記憶體就必須釋放多少個位元組的記憶體" 這個基本原則, 在現在個人電腦動輒有一兩 Giga bytes 的記憶體, 很容易給人一種錯覺, 覺得少釋放幾十個 bytes 應該沒有什麼了不起的, 甚至很難看到系統因此而當掉; 不過這是一種習慣, 一旦養成這種習慣, 你在寫程式時就會常常忘記釋放記憶體, 一旦你的程式必須在資源有限的硬體上來運作, 例如: 手機, PDA, 嵌入式系統, 硬體配件 (DVD, 相機, ...) (這些都是目前台灣賺錢的產品), 那不但會讓自己的程式死掉, 也會害整個機器無法運作下去, 一個工作團隊裡如果有一個成員有這種習慣, 整個開發團隊常常必須付出幾倍的偵錯時間, 如果不找出來這種錯誤, 最後的產品就是不穩定, 在競爭激烈的市場中一定很快被淘汰。
步驟三

請重新新增一個 testMemLeakage 專案,

新增一個使用 malloc 動態配置記憶體的 main.cpp 檔案如下:

    #include <stdio.h>
    #include <malloc.h>
    #include <conio.h>
    
    void main()
    {
        int *ptr;
        int i;
        ptr = (int *) malloc(100*sizeof(int));
        for (i=0; i<100; i++)
            ptr[i] = i;
        free(ptr);
        printf("請按任意鍵繼續 . . .\n");
        getch();
    }

請 建置 並確定可以執行

[注意: 此處不使用 system("pause"); , 而使用 printf("..."); getch(); 是有特別原因的, Visual Studio 2010 中如果使用 system("pause") 的話, 稍後在步驟四中 crtdbg
沒有辦法在配置記憶體時中斷程式, 協助你找到出問題的記憶體配置敘述; 這個問題在 VC6, VC2002, VC2003, VC2005, VC2008 都沒有發生過]

如果刪掉 free() 那一列的話, 程式還是可以編譯, 可以執行, 但是就有記憶體未釋放的錯誤, 請以下述方法來自動偵測這種錯誤

  1. 將上面程式中 free(ptr); 那一列註解掉

  2. 在此程式最前面加入
        #include "memory_leak.h"
  3. 請下載 memory_leak.hmemory_leak.cpp 到 testMemLeakage資料匣中

  4. 在 Visual Studio 2010 界面中點選選單 專案/加入現有項目, 將 memory_leak.h 及 memory_leak.cpp 加入此專案

  5. 編輯 memory_leak.h, 確定下列定義的常數值為 0
        #define TEST_MEM_LEAKS_BREAK_NUM  0
  6. 在 main() 函式一開始的地方加入下列函式呼叫 的敘述
        set_initial_leak_test();
  7. 請在方案總管中點選 '原始程式檔', 由選單 "專案/testMemLeakage 屬性(P)" 開啟下圖屬性視窗以進行設定


    (參考 MSDN Runtime library 說明)

  8. 編譯,"偵錯/啟動但不偵錯" 執行時會發現沒有任何錯誤, 如下圖



    按下任意鍵後視窗就關起來了 (其實有顯示, 但是一閃而過, 我們需要知道它顯示了什麼? 所以請你用下面方法執行程式)

  9. 可是如果你在 cmd 視窗中執行 (把那個 .exe 檔案拉到命令列視窗中, 按下 enter), 就會看到下列訊息, 告訴你 0x00395540 的位址有 400 個位元組沒有釋放, 注意它印出的那個數字 61 (每個機器, 每個程式出現的數字不一樣)
        c:\...\Lab2-3\Debug> testMemLeakage.exe
    
    	[Leak test being performed]
    	Detected memory leaks!
    	Dumping objects ->
    	{61} normal block at 0x00395540, 400 bytes long.
    	 Data: <                > 00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00
    	Object dump complete.
    如果你覺得這樣子有點麻煩的話, 還有一種方式是運用 MFC 的偵錯環境..., 只是需要的背景知識頗多...
步驟四 當你的程式很大, 有很多的記憶體配置敘述時, 光光知道程式有沒有釋放的記憶體還不太夠, 如果希望透過 memory_leak.h 來找到究竟是哪一個敘述配置的記憶體沒有釋放, 需要編輯 memory_leak.h 檔案, 將其中的
    #define TEST_MEM_LEAKS_BREAK_NUM  0
修改為前一步驟中看到的錯誤訊息裡面的 61
    #define TEST_MEM_LEAKS_BREAK_NUM  61

再 "建置/重建方案" 重建整個專案裡所有程式, 然後請在 cmd 視窗中執行 testMemLeakage, 可以看到下列訊息視窗

或是 (win7~win10)

。。。

點選 "除錯", 開啟除錯視窗

如果你的機器上只安裝了 VC2010, 應該會開啟 VC2010 來偵錯, 如果你的機器有安裝其它版本的 VC, 會出現選單讓你挑選:

請挑選 testMemLeakage - Microsoft Visual Studio: Visual Studio 2010 那個, 按下 "是" 以後

請注意: 如果你的機器和 201/203 PC 教室一樣安裝了 win10 1709 + Visual Studio 2017 + Visual Studio 2015 + Visual Studio 2010, 可能是這些版本的程式互相之間有一些衝突, 導致上面的步驟無法啟動 JIT 偵錯工具, 試看看在 "建置/重建方案" 重建整個專案裡所有程式以後, 直接按下 "偵錯/開始偵錯"

可以看到下面 Debugger 的畫面:

程式中斷在 dbgheap.c 的 _heap_alloc_dbg_impl() 這個函式裡面, 這不是你寫的, 但是從上面的呼叫堆疊中可以看到, 你的程式 main() 第 10 列呼叫 malloc() 然後呼叫 _nh_malloc_dbg() 然後呼叫 _nh_malloc_dbg_impl() 然後呼叫 _heap_alloc_dbg_impl();

你可以用滑鼠雙擊 testMemLeakage.exe!main() 這一列, 程式編輯視窗就會跳到呼叫 malloc() 那一列 (main 的第 10 列), 這個地方配置的記憶體就是沒有釋放掉的記憶體

如果你的偵錯環境中沒有顯示 呼叫堆疊 視窗的話, 你可以在選單 偵錯/視窗選項中找到 (Alt+7), 把 呼叫堆疊 視窗顯示出來

步驟五 請撰寫一個使用 C++ 的 new 配置記憶體, 使用 delete[] 釋放記憶體的程式如下:
    void main()
    {
        int *ptr;
        int i;

        ptr = new int[100];
        for (i=0; i<100; i++)
            ptr[i] = i;
//        delete ptr;  // 這是一個非常容易犯的錯誤
        delete[] ptr;
    }

請將 delete[] ptr 這一列註解掉, 重複步驟三和步驟四的測試。

注意: 如果你使用 ptr = new int[100]; 來配置記憶體, 但是使用 delete ptr; 來刪除, 或是使用 ptr = new int; 來配置記憶體, 但是使用 delete[] ptr; 來刪除, memory_leak 毫無作用, 完全偵測不到, 可是卻一定有 memeory leakage, 這還蠻糟糕的, 需要使用別的工具來找, 我也還不知道有哪一個工具可以自動偵測, 所以請特別留意不要出現這種要命的記憶體錯誤

另外請注意如果你在建置或是重建專案的時候, 前一次執行的程式沒有關閉, 或是開了另一個視窗用檔案總管看 Debug\ 資料匣, 你的建置會失敗 (注意看建置的輸出訊息), 建置失敗當然就不會有你預期的結果

步驟六 請向助教說明你如何找到是哪一列的記憶體配置敘述錯誤, 將所完成的專案 (只需保留 .cpp, .h, .sln 以及 .vcxproj 檔案即可; 刪除掉 .sdf, .filters, .users, debug\ 資料匣, 以及 ipch\ 資料匣下的所有內容) 壓縮起來, 選擇 Lab2-3 上傳 (步驟三的 C 版本和步驟五的 C++ 版本可以分別上傳一次)

在你自己的系統上, 如果你有灌其他的開發環境 (例如 visual studio 2008), 執行程式發生錯誤時系統 可能 不會執行 VC2010 的 debugger, 如果你在下圖選單中找不到, 你可以用下列設定可以改變系統預設的偵錯環境 (你需要有適當的權限)

確定 "原生" 有勾選


   
 

Valgrind @ linux

(valgrind-3.11.0 supports X86/Linux, AMD64/Linux, ARM/Linux, ARM64/Linux, PPC32/Linux, PPC64/Linux, PPC64LE/Linux, S390X/Linux, MIPS32/Linux, MIPS64/Linux, TILEGX/Linux, X86/Solaris, AMD64/Solaris, ARM/Android (2.3.x and later), ARM64/Android, X86/Android (4.0 and later), MIPS32/Android, X86/Darwin and AMD64/Darwin (Mac OS X 10.10, with initial support for 10.11))
   
下面這個簡單的 C 程式裡有三個錯誤, 讓我們用 Valgrind 來檢查這些
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int *ptr;
    ptr = (int *) malloc(100*sizeof(int));

    ptr[100] = 10; // buffer overflow
    ptr[-1] = -1; // buffer underflow
    
    return 0; // memory leakage
}

g++ testValgrind.cpp -o testValgrind
valgrind --tool=memcheck ./testValgrind

==25532== Memcheck, a memory error detector for x86-linux.
==25532== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==25532== Using valgrind-2.2.0, a program supervision framework for x86-linux.
==25532== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==25532== For more details, rerun with: -v
==25532==
==25532== Invalid write of size 4
==25532==    at 0x80483C7: main (in /home/pyting/tmp/testValgrind)
==25532==  Address 0x1B91F1B8 is 0 bytes after a block of size 400 alloc'd
==25532==    at 0x1B902A90: malloc (vg_replace_malloc.c:131)
==25532==    by 0x80483B8: main (in /home/pyting/tmp/testValgrind)
==25532==
==25532== Invalid write of size 4
==25532==    at 0x80483D3: main (in /home/pyting/tmp/testValgrind)
==25532==  Address 0x1B91F024 is 4 bytes before a block of size 400 alloc'd
==25532==    at 0x1B902A90: malloc (vg_replace_malloc.c:131)
==25532==    by 0x80483B8: main (in /home/pyting/tmp/testValgrind)
==25532==
==25532== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 15 from 1)
==25532== malloc/free: in use at exit: 400 bytes in 1 blocks.
==25532== malloc/free: 1 allocs, 0 frees, 400 bytes allocated.
==25532== For a detailed leak analysis,  rerun with: --leak-check=yes
==25532== For counts of detected errors, rerun with: -v

g++ testValgrind.cpp -o testValgrind
valgrind --tool=memcheck -v ./testValgrind

==25952== Memcheck, a memory error detector for x86-linux.
==25952== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==25952== Using valgrind-2.2.0, a program supervision framework for x86-linux.
==25952== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==25952== Valgrind library directory: /usr/lib/valgrind
==25952== Command line
==25952==    ./testValgrind
==25952== Startup, with flags:
==25952==    --tool=memcheck
==25952==    -v
==25952== Contents of /proc/version:
==25952==   Linux version 2.6.9-1.667 (bhcompile@tweety.build.redhat.com) (gcc version 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)) #1 Tue Nov 2 14:41:25 EST 2004
==25952== Reading syms from /home/pyting/tmp/testValgrind (0x8048000)
==25952==    object doesn't have any debug info
==25952== Reading syms from /lib/ld-2.3.3.so (0x1B8E4000)
==25952==    object doesn't have any debug info
==25952== Reading syms from /usr/lib/valgrind/stage2 (0xB0000000)
==25952== Reading syms from /lib/ld-2.3.3.so (0xB1000000)
==25952==    object doesn't have any debug info
==25952== Reading syms from /usr/lib/valgrind/vgskin_memcheck.so (0xF6C97000)
==25952== Reading syms from /lib/tls/libc-2.3.3.so (0xF6EC1000)
==25952==    object doesn't have any debug info
==25952== Reading syms from /lib/libdl-2.3.3.so (0xF6FE8000)
==25952==    object doesn't have any debug info
==25952== Reading suppressions file: /usr/lib/valgrind/default.supp
==25952== REDIRECT soname:libc.so.6(__GI___errno_location) to soname:libpthread.so.0(__errno_location)
==25952== REDIRECT soname:libc.so.6(__errno_location) to soname:libpthread.so.0(__errno_location)
==25952== REDIRECT soname:libc.so.6(__GI___h_errno_location) to soname:libpthread.so.0(__h_errno_location)
==25952== REDIRECT soname:libc.so.6(__h_errno_location) to soname:libpthread.so.0(__h_errno_location)
==25952== REDIRECT soname:libc.so.6(__GI___res_state) to soname:libpthread.so.0(__res_state)
==25952== REDIRECT soname:libc.so.6(__res_state) to soname:libpthread.so.0(__res_state)
==25952== REDIRECT soname:libc.so.6(stpcpy) to *vgpreload_memcheck.so*(stpcpy)
==25952== REDIRECT soname:libc.so.6(strnlen) to *vgpreload_memcheck.so*(strnlen)
==25952== REDIRECT soname:ld-linux.so.2(stpcpy) to *vgpreload_memcheck.so*(stpcpy)
==25952== REDIRECT soname:ld-linux.so.2(strchr) to *vgpreload_memcheck.so*(strchr)
==25952== 
==25952== Reading syms from /usr/lib/valgrind/vg_inject.so (0x1B8FC000)
==25952== Reading syms from /usr/lib/valgrind/vgpreload_memcheck.so (0x1B8FF000)
==25952== TRANSLATE: 0x1B8F5A50 redirected to 0x1B90220C
==25952== Reading syms from /usr/lib/libstdc++.so.6.0.3 (0xC10000)
==25952==    object doesn't have a symbol table
==25952==    object doesn't have any debug info
==25952== Reading syms from /lib/tls/libm-2.3.3.so (0x8DD000)
==25952==    object doesn't have any debug info
==25952== Reading syms from /lib/libgcc_s-3.4.2-20041018.so.1 (0xBE6000)
==25952==    object doesn't have a symbol table
==25952==    object doesn't have any debug info
==25952== Reading syms from /lib/tls/libc-2.3.3.so (0x7B4000)
==25952==    object doesn't have any debug info
==25952== TRANSLATE: 0x817160 redirected to 0x1B902A04
==25952== Invalid write of size 4
==25952==    at 0x80483C7: main (in /home/pyting/tmp/testValgrind)
==25952==  Address 0x1B91F1B8 is 0 bytes after a block of size 400 alloc'd
==25952==    at 0x1B902A90: malloc (vg_replace_malloc.c:131)
==25952==    by 0x80483B8: main (in /home/pyting/tmp/testValgrind)
==25952== 
==25952== Invalid write of size 4
==25952==    at 0x80483D3: main (in /home/pyting/tmp/testValgrind)
==25952==  Address 0x1B91F024 is 4 bytes before a block of size 400 alloc'd
==25952==    at 0x1B902A90: malloc (vg_replace_malloc.c:131)
==25952==    by 0x80483B8: main (in /home/pyting/tmp/testValgrind)
==25952== TRANSLATE: 0x1B8E47A0 redirected to 0x52BFF040
==25952== TRANSLATE: 0x815430 redirected to 0x1B902F30
==25952== 
==25952== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 15 from 1)
==25952== 
==25952== 1 errors in context 1 of 2:
==25952== Invalid write of size 4
==25952==    at 0x80483D3: main (in /home/pyting/tmp/testValgrind)
==25952==  Address 0x1B91F024 is 4 bytes before a block of size 400 alloc'd
==25952==    at 0x1B902A90: malloc (vg_replace_malloc.c:131)
==25952==    by 0x80483B8: main (in /home/pyting/tmp/testValgrind)
==25952== 
==25952== 1 errors in context 2 of 2:
==25952== Invalid write of size 4
==25952==    at 0x80483C7: main (in /home/pyting/tmp/testValgrind)
==25952==  Address 0x1B91F1B8 is 0 bytes after a block of size 400 alloc'd
==25952==    at 0x1B902A90: malloc (vg_replace_malloc.c:131)
==25952==    by 0x80483B8: main (in /home/pyting/tmp/testValgrind)
--25952-- 
--25952-- supp:   15 Ugly strchr error in /lib/ld-2.3.3.so
==25952== 
==25952== IN SUMMARY: 2 errors from 2 contexts (suppressed: 15 from 1)
==25952== 
==25952== malloc/free: in use at exit: 400 bytes in 1 blocks.
==25952== malloc/free: 1 allocs, 0 frees, 400 bytes allocated.
==25952== 
--25952--     TT/TC: 0 tc sectors discarded.
--25952--            2012 tt_fast misses.
--25952-- translate: new     1882 (33357 -> 438568; ratio 131:10)
--25952--            discard 1 (23 -> 320; ratio 139:10).
--25952-- chainings: 1202 chainings, 2 unchainings.
--25952--  dispatch: 250000 jumps (bb entries); of them 18698 (7%) unchained.
--25952--            27/2087 major/minor sched events.
--25952-- reg-alloc: 414 t-req-spill, 81620+3575 orig+spill uis,
--25952--            10349 total-reg-rank
--25952--    sanity: 28 cheap, 2 expensive checks.
--25952--    ccalls: 7151 C calls, 55% saves+restores avoided (23202 bytes)
--25952--            9446 args, avg 0.87 setup instrs each (2400 bytes)
--25952--            0% clear the stack (21396 bytes)
--25952--            3205 retvals, 29% of reg-reg movs avoided (1820 bytes)

g++ testValgrind.cpp -o testValgrind

valgrind --tool=memcheck --leak-check=yes -v ./testValgrind

==25906== Memcheck, a memory error detector for x86-linux.
==25906== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==25906== Using valgrind-2.2.0, a program supervision framework for x86-linux.
==25906== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==25906== Valgrind library directory: /usr/lib/valgrind
==25906== Command line
==25906== ./testValgrind
==25906== Startup, with flags:
==25906== --tool=memcheck
==25906== --leak-check=yes
==25906== -v
==25906== Contents of /proc/version:
==25906== Linux version 2.6.9-1.667 (bhcompile@tweety.build.redhat.com) (gcc version 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)) #1 Tue Nov 2 14:41:25 EST 2004
==25906== Reading syms from /home/pyting/tmp/testValgrind (0x8048000)
==25906== object doesn't have any debug info
==25906== Reading syms from /lib/ld-2.3.3.so (0x1B8E4000)
==25906== object doesn't have any debug info
==25906== Reading syms from /usr/lib/valgrind/stage2 (0xB0000000)
==25906== Reading syms from /lib/ld-2.3.3.so (0xB1000000)
==25906== object doesn't have any debug info
==25906== Reading syms from /usr/lib/valgrind/vgskin_memcheck.so (0xF6C97000)
==25906== Reading syms from /lib/tls/libc-2.3.3.so (0xF6EC1000)
==25906== object doesn't have any debug info
==25906== Reading syms from /lib/libdl-2.3.3.so (0xF6FE8000)
==25906== object doesn't have any debug info
==25906== Reading suppressions file: /usr/lib/valgrind/default.supp
==25906== REDIRECT soname:libc.so.6(__GI___errno_location) to soname:libpthread.so.0(__errno_location)
==25906== REDIRECT soname:libc.so.6(__errno_location) to soname:libpthread.so.0(__errno_location)
==25906== REDIRECT soname:libc.so.6(__GI___h_errno_location) to soname:libpthread.so.0(__h_errno_location)
==25906== REDIRECT soname:libc.so.6(__h_errno_location) to soname:libpthread.so.0(__h_errno_location)
==25906== REDIRECT soname:libc.so.6(__GI___res_state) to soname:libpthread.so.0(__res_state)
==25906== REDIRECT soname:libc.so.6(__res_state) to soname:libpthread.so.0(__res_state)
==25906== REDIRECT soname:libc.so.6(stpcpy) to *vgpreload_memcheck.so*(stpcpy)
==25906== REDIRECT soname:libc.so.6(strnlen) to *vgpreload_memcheck.so*(strnlen)
==25906== REDIRECT soname:ld-linux.so.2(stpcpy) to *vgpreload_memcheck.so*(stpcpy)
==25906== REDIRECT soname:ld-linux.so.2(strchr) to *vgpreload_memcheck.so*(strchr)
==25906==
==25906== Reading syms from /usr/lib/valgrind/vg_inject.so (0x1B8FC000)
==25906== Reading syms from /usr/lib/valgrind/vgpreload_memcheck.so (0x1B8FF000)
==25906== TRANSLATE: 0x1B8F5A50 redirected to 0x1B90220C
==25906== Reading syms from /usr/lib/libstdc++.so.6.0.3 (0xC10000)
==25906== object doesn't have a symbol table
==25906== object doesn't have any debug info
==25906== Reading syms from /lib/tls/libm-2.3.3.so (0x8DD000)
==25906== object doesn't have any debug info
==25906== Reading syms from /lib/libgcc_s-3.4.2-20041018.so.1 (0xBE6000)
==25906== object doesn't have a symbol table
==25906== object doesn't have any debug info
==25906== Reading syms from /lib/tls/libc-2.3.3.so (0x7B4000)
==25906== object doesn't have any debug info
==25906== TRANSLATE: 0x817160 redirected to 0x1B902A04
==25906== Invalid write of size 4
==25906== at 0x80483C7: main (in /home/pyting/tmp/testValgrind)
==25906== Address 0x1B91F1B8 is 0 bytes after a block of size 400 alloc'd
==25906== at 0x1B902A90: malloc (vg_replace_malloc.c:131)
==25906== by 0x80483B8: main (in /home/pyting/tmp/testValgrind)
==25906==
==25906== Invalid write of size 4
==25906== at 0x80483D3: main (in /home/pyting/tmp/testValgrind)
==25906== Address 0x1B91F024 is 4 bytes before a block of size 400 alloc'd
==25906== at 0x1B902A90: malloc (vg_replace_malloc.c:131)
==25906== by 0x80483B8: main (in /home/pyting/tmp/testValgrind)
==25906== TRANSLATE: 0x1B8E47A0 redirected to 0x52BFF040
==25906== TRANSLATE: 0x815430 redirected to 0x1B902F30
==25906==
==25906== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 15 from 1)
==25906==
==25906== 1 errors in context 1 of 2:
==25906== Invalid write of size 4
==25906== at 0x80483D3: main (in /home/pyting/tmp/testValgrind)
==25906== Address 0x1B91F024 is 4 bytes before a block of size 400 alloc'd
==25906== at 0x1B902A90: malloc (vg_replace_malloc.c:131)
==25906== by 0x80483B8: main (in /home/pyting/tmp/testValgrind)
==25906==
==25906== 1 errors in context 2 of 2:
==25906== Invalid write of size 4
==25906== at 0x80483C7: main (in /home/pyting/tmp/testValgrind)
==25906== Address 0x1B91F1B8 is 0 bytes after a block of size 400 alloc'd
==25906== at 0x1B902A90: malloc (vg_replace_malloc.c:131)
==25906== by 0x80483B8: main (in /home/pyting/tmp/testValgrind)
--25906--
--25906-- supp: 15 Ugly strchr error in /lib/ld-2.3.3.so
==25906==
==25906== IN SUMMARY: 2 errors from 2 contexts (suppressed: 15 from 1)
==25906==
==25906== malloc/free: in use at exit: 400 bytes in 1 blocks.
==25906== malloc/free: 1 allocs, 0 frees, 400 bytes allocated.
==25906==
==25906== searching for pointers to 1 not-freed blocks.
==25906== checked 2364916 bytes.
==25906==
==25906==
==25906== 400 bytes in 1 blocks are definitely lost in loss record 1 of 1
==25906== at 0x1B902A90: malloc (vg_replace_malloc.c:131)
==25906== by 0x80483B8: main (in /home/pyting/tmp/testValgrind)
==25906==
==25906== LEAK SUMMARY:
==25906== definitely lost: 400 bytes in 1 blocks.
==25906== possibly lost: 0 bytes in 0 blocks.
==25906== still reachable: 0 bytes in 0 blocks.
==25906== suppressed: 0 bytes in 0 blocks.
==25906== Reachable blocks (those to which a pointer was found) are not shown.
==25906== To see them, rerun with: --show-reachable=yes
--25906-- TT/TC: 0 tc sectors discarded.
--25906-- 2012 tt_fast misses.
--25906-- translate: new 1882 (33357 -> 438568; ratio 131:10)
--25906-- discard 1 (23 -> 320; ratio 139:10).
--25906-- chainings: 1202 chainings, 2 unchainings.
--25906-- dispatch: 250000 jumps (bb entries); of them 18698 (7%) unchained.
--25906-- 27/2087 major/minor sched events.
--25906-- reg-alloc: 414 t-req-spill, 81620+3575 orig+spill uis,
--25906-- 10349 total-reg-rank
--25906-- sanity: 28 cheap, 2 expensive checks.
--25906-- ccalls: 7151 C calls, 55% saves+restores avoided (23202 bytes)
--25906-- 9446 args, avg 0.87 setup instrs each (2400 bytes)
--25906-- 0% clear the stack (21396 bytes)
--25906-- 3205 retvals, 29% of reg-reg movs avoided (1820 bytes)

 

C++ 物件導向程式設計課程 首頁

製作日期: 03/06/2013 by 丁培毅 (Pei-yih Ting)
E-mail: pyting@mail.ntou.edu.tw TEL: 02 24622192x6615
海洋大學 電機資訊學院 資訊工程學系 Lagoon