上次,我们提到利用google gperftools定位程序cpu使用性能问题,这次利用同样的工具的heap checker的功能对程序进行内存泄漏的定位。安装请看之前的文章:
#include <iostream>
#include <vector>
using namespace std;
extern "C" {
#include <string.h>
}
class MyClass {
private:
char* str;
public:
MyClass(const char* s) {
cout<<"construct MyClass\n";
str = new char[strlen(s)];
strcpy(str, s);
}
~MyClass() {
cout<<"~MyClass\n";
//delete str;//我们把这一行注释掉
}
MyClass(const MyClass& mc) {
cout<<"copy MyClass\n";
delete str;
str = new char[strlen(mc.str)];
strcpy(str, mc.str);
}
MyClass& operator= (const MyClass& mc) {
cout<<"operator=(&)\n";
if(this != &mc) {
delete str;
str = new char[strlen(mc.str)];
strcpy(str, mc.str);
}
}
friend ostream& operator << (ostream& os, MyClass& mc) {
os<<mc.str;
return os;
}
MyClass& operator = (MyClass&& mc) {
cout<<"operator = &&\n";
if(this != &mc) {
this->str = mc.str;
mc.str = NULL;
}
}
MyClass(MyClass&& mc) {
cout<<"MyClass &&\n";
this->str = mc.str;
mc.str = NULL;
}
};
vector<MyClass> makeMcVec() {
vector<MyClass> v;
v.reserve(3);
v.push_back(MyClass("Hello World"));
v.push_back(MyClass("\n"));
return v;
}
vector<MyClass> makeMcVec1() {
vector<MyClass> v;
v.reserve(3);
MyClass a("Hello World");
MyClass b("\n");
v.push_back(move(a));
v.push_back(move(b));
return v;
}
int main() {
vector<MyClass> mvVec = makeMcVec1();
cout<<"after makeMcVec\n";
for(auto it = mvVec.begin(); it != mvVec.end(); it++) {
cout<<*it;
}
return 0;
}
我们拿之前一个右值引用的例子,把析构函数里面的delete去注释掉。
然后进行以下命令:
g++ -g -o MyClass MyClass.cpp -std=c++11 -ltcmalloc //链接tcmalloc
export PPROF_PATH=/usr/local/bin/pprof
env HEAPCHECK=normal /home/oujiangping/project/blog/MyClass
结果如下:
WARNING: Perftools heap leak checker is active -- Performance may suffer
construct MyClass
construct MyClass
MyClass &&
MyClass &&
~MyClass
~MyClass
after makeMcVec
Hello World
~MyClass
~MyClass
Have memory regions w/o callers: might report false leaks
Leak check _main_ detected leaks of 12 bytes in 2 objects
The 2 largest leaks:
Using local file /home/oujiangping/project/blog/MyClass.
Leak of 11 bytes in 1 objects allocated from:
@ 401053 MyClass::MyClass
@ 400e07 makeMcVec1
@ 400eef main
@ 7f632931d830 __libc_start_main
@ 400bf9 _start
Leak of 1 bytes in 1 objects allocated from:
@ 401053 MyClass::MyClass
@ 400e18 makeMcVec1
@ 400eef main
@ 7f632931d830 __libc_start_main
@ 400bf9 _start
If the preceding stack traces are not enough to find the leaks, try running THIS shell command:
pprof /home/oujiangping/project/blog/MyClass "/tmp/MyClass.15222._main_-end.heap" --inuse_objects --lines --heapcheck --edgefraction=1e-10 --nodefraction=1e-10 --gv
If you are still puzzled about why the leaks are there, try rerunning this program with HEAP_CHECK_TEST_POINTER_ALIGNMENT=1 and/or with HEAP_CHECK_MAX_POINTER_OFFSET=-1
If the leak report occurs in a small fraction of runs, try running with TCMALLOC_MAX_FREE_QUEUE_SIZE of few hundred MB or with TCMALLOC_RECLAIM_MEMORY=false, it mi
Exiting with error code (instead of crashing) because of whole-program memory leaks
函数指出了makeVec1中调用MyClass存在两次内存泄漏分别是11字节和1字节,其实就是使用“Hello world”和“\n”创建的字符串,可以看到构造函数中有一个new语句,没有释放,在析构函数中delete就好了。