C/C++中内存泄露常见的有3种:
1、malloc、realloc后忘记了free;new后忘记了delete;new []后忘记了delete[]。
2、采用使用计数的方式管理内存,两个使用计数指针相互指向,导致内存泄露。
3、将分配且使用完的内存的放到了容器里。
其中,第3中内存泄露方式在Java、C#等自动释放内存的语言中也存在。
下面是第2种情况导致内存泄露的例子:
ValgrindMemcheck.cpp
#include <iostream>
class A;
class B;
class A
{
public:
A()
:b(0),cnt(0)
{}
A(B *pB)
:b(pB),cnt(new int(1))
{}
A(const A &a)
:b(a.b),cnt(a.cnt)
{
++*cnt;
}
A &operator =(const A &a);
~A();
private:
B *b;
int *cnt;
};
class B
{
public:
B()
:a(0),cnt(0)
{}
B(A *pA)
:a(pA),cnt(new int (1))
{}
B(const B &b)
:a(b.a),cnt(b.cnt)
{
++*cnt;
}
B &operator =(const B &b);
~B();
private:
A *a;
int *cnt;
};
A &A::operator =(const A &a)
{
if(this == &a)
return *this;
if(cnt && 0 == --*cnt)
{
delete b;
delete cnt;
}
b = a.b;
cnt = a.cnt;
++*cnt;
return *this;
}
A::~A()
{
if(cnt && 0 == --*cnt)
{
delete b;
delete cnt;
}
}
B &B::operator =(const B &b)
{
if(this == &b)
return *this;
if(cnt && 0 == --*cnt)
{
delete a;
delete cnt;
}
a = b.a;
cnt = b.cnt;
++*cnt;
return *this;
}
B::~B()
{
if(cnt && 0 == --*cnt)
{
delete a;
delete cnt;
}
}
void test0()
{
A a0;
B b0;
A a1(new B());
B b1(new A());
}
void test1()
{
A *pA = new A();
B *pB = new B();
B b(pA);
A a(pB);
}
void test2()
{
A a;
B b;
a = &b;
b = &a;
}
int main(void)
{
test0();
test1();
test2();
return 0;
}
Makefile
all:ValgrindMemcheck
ValgrindMemcheck:ValgrindMemcheck.o
g++ -g -Wall -o $@ $^
ValgrindMemcheck.o:ValgrindMemcheck.cpp
g++ -g -Wall -o $@ -c $<
.PHONY:
clean:
- $(RM) ValgrindMemcheck.cpp
- $(RM) ValgrindMemcheck.o
请问,test0、test1、test2中哪个有内存泄露呢?
运行:
valgrind --leak-check=full ./ValgrindMemcheck
就会发现test2中有内存问题。
参考文献:
http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/
推荐几个博文:
http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/
http://blog.dccmx.com/2011/01/valgrind-massif/
http://blog.dccmx.com/2011/01/callgrind/
http://blog.dccmx.com/2011/01/gprof/
http://blog.dccmx.com/2011/01/valgrind-memcheck/