目錄
內存泄露
示例代碼
// MemoryLeak.cpp : 定義控制檯應用程序的入口點。
//
#include <stdlib.h>
#include <string>
char* AllocateMemory(size_t nSize)
{
return new char[nSize];
}
int main()
{
size_t nSize = 16;
char* pszData = AllocateMemory(nSize);
// do something
return 0;
}
編譯:g++ -Wall -g MemoryLeak.cpp -o MemoryLeak
執行:valgrind --log-file=MemoryLeak.log --tool=memcheck --leak-check=full -v ./MemoryLeak
MemoryLeak.log內容如下:
==14736== Memcheck, a memory error detector ==14736== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==14736== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==14736== Command: ./MemoryLeak ==14736== Parent PID: 3836 ==14736== ==14736== ==14736== HEAP SUMMARY: ==14736== in use at exit: 16 bytes in 1 blocks ==14736== total heap usage: 2 allocs, 1 frees, 72,720 bytes allocated ==14736== ==14736== 16 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==14736== at 0x4C3089F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==14736== by 0x108691: AllocateMemory(unsigned long) (MemoryLeak.cpp:9) ==14736== by 0x1086AF: main (MemoryLeak.cpp:15) ==14736== ==14736== LEAK SUMMARY: ==14736== definitely lost: 16 bytes in 1 blocks ==14736== indirectly lost: 0 bytes in 0 blocks ==14736== possibly lost: 0 bytes in 0 blocks ==14736== still reachable: 0 bytes in 0 blocks ==14736== suppressed: 0 bytes in 0 blocks ==14736== ==14736== For counts of detected and suppressed errors, rerun with: -v ==14736== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) |
由於申請的16字節的內存沒有釋放,因此被檢測出16字節的泄露。
重複釋放
示例代碼
// MemoryDoubleFree.cpp : 定義控制檯應用程序的入口點。
//
#include <stdlib.h>
#include <string>
char* AllocateMemory(size_t nSize)
{
return new char[nSize];
}
void FreeMemory(char* pData)
{
if (!pData)
{
return;
}
delete[] pData;
pData = NULL;
}
int main()
{
size_t nSize = 16;
char* pszData = AllocateMemory(nSize);
// do something
FreeMemory(pszData);
FreeMemory(pszData);
return 0;
}
編譯:g++ -Wall -g MemoryDoubleFree.cpp -o MemoryDoubleFree
執行:valgrind --log-file= MemoryDoubleFree.log --tool=memcheck --leak-check=full ./ MemoryDoubleFree
MemoryDoubleFree.log內容如下:
==15027== Memcheck, a memory error detector ==15027== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==15027== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==15027== Command: ./MemoryDoubleFree ==15027== Parent PID: 3836 ==15027== ==15027== Invalid free() / delete / delete[] / realloc() ==15027== at 0x4C3173B: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==15027== by 0x108709: FreeMemory(char*) (MemoryDoubleFree.cpp:19) ==15027== by 0x10874E: main (MemoryDoubleFree.cpp:30) ==15027== Address 0x5b7dc80 is 0 bytes inside a block of size 16 free'd ==15027== at 0x4C3173B: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==15027== by 0x108709: FreeMemory(char*) (MemoryDoubleFree.cpp:19) ==15027== by 0x108742: main (MemoryDoubleFree.cpp:29) ==15027== Block was alloc'd at ==15027== at 0x4C3089F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==15027== by 0x1086E1: AllocateMemory(unsigned long) (MemoryDoubleFree.cpp:9) ==15027== by 0x108732: main (MemoryDoubleFree.cpp:26) ==15027== ==15027== ==15027== HEAP SUMMARY: ==15027== in use at exit: 0 bytes in 0 blocks ==15027== total heap usage: 2 allocs, 3 frees, 72,720 bytes allocated ==15027== ==15027== All heap blocks were freed -- no leaks are possible ==15027== ==15027== For counts of detected and suppressed errors, rerun with: -v ==15027== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) |
申請的16字節的內存被釋放了兩次,屬於重複釋放。此種情況,不同編譯器編譯出的可執行程序的現象也不同,同時,也和內存的使用與回收情況有關。有的直接奔潰,有的可以暫時正常運行。
錯誤釋放
示例代碼
// MemoryCheck.cpp : 定義控制檯應用程序的入口點。
//
#include <stdlib.h>
#include <string>
char* Serialize(size_t& nSize)
{
std::string strData = "This is a MemCheck Programm With Valgrind";
nSize = strData.size();
return (char*)strData.c_str();
}
int main()
{
size_t nSize = 0;
char* pszData = Serialize(nSize);
// do something
delete[] pszData;
pszData = NULL;
return 0;
}
編譯運行:g++ -Wall -g MemoryCheck.cpp -o MemoryCheck
執行:valgrind --log-file= MemoryCheck.log --tool=memcheck --leak-check=full ./MemoryCheck
MemoryCheck.log內容如下:
==15124== Memcheck, a memory error detector ==15124== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==15124== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==15124== Command: ./MemoryCheck ==15124== Parent PID: 3836 ==15124== ==15124== Invalid free() / delete / delete[] / realloc() ==15124== at 0x4C3173B: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==15124== by 0x108B81: main (MemoryCheck.cpp:22) ==15124== Address 0x5b7dc80 is 0 bytes inside a block of size 42 free'd ==15124== at 0x4C3123B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==15124== by 0x108B05: Serialize(unsigned long&) (MemoryCheck.cpp:9) ==15124== by 0x108B6A: main (MemoryCheck.cpp:18) ==15124== Block was alloc'd at ==15124== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==15124== by 0x4F633AC: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25) ==15124== by 0x108AC8: Serialize(unsigned long&) (MemoryCheck.cpp:9) ==15124== by 0x108B6A: main (MemoryCheck.cpp:18) ==15124== ==15124== ==15124== HEAP SUMMARY: ==15124== in use at exit: 0 bytes in 0 blocks ==15124== total heap usage: 2 allocs, 3 frees, 72,746 bytes allocated ==15124== ==15124== All heap blocks were freed -- no leaks are possible ==15124== ==15124== For counts of detected and suppressed errors, rerun with: -v ==15124== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) |
由於strData的內存已經釋放(生命週期在Serialize函數),隨後通過delete[] 釋放已經釋放的資源,因此報錯。但是,程序表現可能很正常的退出,這個和編譯器有關,不同編譯器有不同表現,同時,也和內存的使用與回收情況有關。
相關資料