内存泄漏检测工具valgrind

11 篇文章 0 订阅

valgrind的工具

示例1:

class Person
{
public:

	Person(int age)
	{
		//将年龄数据开辟到堆区
		m_Age = new int(age);
	}

	//重载赋值运算符 写法2 此代码在linux测试
	Person& operator=(Person& p)
	{
		*m_Age = *p.m_Age;  //通过linux下valgrind工具检测,无内存泄漏情况。
        //此语句是把this->m_age所指向的内存里的值,将20替换成18
		//返回自身
		return *this;
	}

	~Person()
	{
		if (m_Age != NULL)
		{
			delete m_Age;
			m_Age = NULL;
		}
	}

	//年龄的指针
	int *m_Age;

};


void test01()
{
	Person p1(18);
	Person p2(20);    
	Person p3(30);   
	p3 = p2 = p1; //赋值操作    
	cout << "p1的年龄为:" << *p1.m_Age << endl;    
	cout << "p2的年龄为:" << *p2.m_Age << endl;   
	cout << "p3的年龄为:" << *p3.m_Age << endl;
}

int main() {

	test01();

	return 0;
}

holo@jiayinhao:~/test$ valgrind ./shenkaobei
22518 Memcheck, a memory error detector
22518 Copyright © 2002-2013, and GNU GPL’d, by Julian Seward et al.
22518 Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info== 版本号==
22518 Command: ./shenkaobei
22518 22518是进程号
p1的年龄为:18
p2的年龄为:18
p3的年龄为:18
22518
22518 HEAP SUMMARY:
22518 in use at exit: 0 bytes in 0 blocks
22518 total heap usage: 3 allocs, 3 frees, 12 bytes allocated 堆空间使用情况:申请三次,释放3次
22518
22518 All heap blocks were freed – no leaks are possible
22518
22518 For counts of detected and suppressed errors, rerun with: -v
22518 ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 错误总结:没有错误

四种情况示例

#include <stdio.h>
#include <stdlib.h>

int main()
{
        //内存泄漏
        char *p1 = (char *)malloc(sizeof(char) * 128);

        //越界访问
        int *p2 = (int *)malloc(sizeof(int) * 5);
        p2[5] = 1;  // Invalid write of size 4
        free(p2);

        //未初始化的内存
        char *p3; //野指针
        char ch = *p3;  // Use of uninitialised value of size 8

        //使用已经释放的内存
        char *p4 = (char *)malloc(sizeof(char) * 8);
        free(p4);
        p4[0] = 'a';  //Invalid write of size 1

        return 0;

}

编译时带上-g选项,用valgrind工具执行时才会显示内存泄漏错误所在的行号

holo@jiayinhao:~/test$ gcc valgrind_test.c -o valgrind_test -g

holo@jiayinhao:~/test$ valgrind ./valgrind_test
22586 Memcheck, a memory error detector
22586 Copyright © 2002-2013, and GNU GPL’d, by Julian Seward et al.
22586 Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
22586 Command: ./valgrind_test
22586
22586 Invalid write of size 4
22586 at 0x4005A9: main (valgrind_test.c:11)
22586 Address 0x5200114 is 0 bytes after a block of size 20 alloc’d
22586 at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
22586 by 0x40059C: main (valgrind_test.c:10)
22586
22586 Use of uninitialised value of size 8
22586 at 0x4005BF: main (valgrind_test.c:16)
22586
22586 Invalid write of size 1
22586 at 0x4005E3: main (valgrind_test.c:21)
22586 Address 0x5200160 is 0 bytes inside a block of size 8 free’d
22586 at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
22586 by 0x4005DE: main (valgrind_test.c:20)
22586
22586
22586 HEAP SUMMARY: //堆内存的使用情况
22586 in use at exit: 128 bytes in 1 blocks
22586 total heap usage: 3 allocs, 2 frees, 156 bytes allocated //申请了三次释放了两次
22586
22586 LEAK SUMMARY: 内存泄露情况汇总
22586 definitely lost: 128 bytes in 1 blocks
22586 indirectly lost: 0 bytes in 0 blocks
22586 possibly lost: 0 bytes in 0 blocks
22586 still reachable: 0 bytes in 0 blocks
22586 suppressed: 0 bytes in 0 blocks
22586 Rerun with --leak-check=full to see details of leaked memory
22586
22586 For counts of detected and suppressed errors, rerun with: -v
22586 Use --track-origins=yes to see where uninitialised values come from
22586 ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0) //总结:有三个(内存泄漏除外)错误

示例2 类模板实现vector部分功能

这个示例来自笔记中的类模板案例.

#include <iostream>
#include <vector>

template <class T>	//是这样定义吗?  存放的数组元素 数据类型是T
//如何防止浅拷贝?  重写两个函数:拷贝构造函数.重载赋值运算符函数
class MyArray
{
public:
	MyArray(int capacity):m_Size(0),m_Capacity(capacity)
	{
		p_Address = new T[this->m_Capacity];	//new T[]?
	}

	MyArray(const MyArray& arr)
	{
		this->m_Capacity = arr.m_Capacity;
		this->m_Size = arr.m_Size;
		p_Address = new T[arr.m_Capacity];
		for (int i = 0; i < this->m_Size; i++)
		{
			p_Address[i] = arr.p_Address[i];
		}
	}

	MyArray& operator=(const MyArray& arr)
	{
		if (this != &arr && this != nullptr)
		{
			this->m_Capacity = arr.m_Capacity;
			this->m_Size = arr.m_Size;
			for (int i = 0; i < this->m_Size; i++)
			{
				p_Address[i] = arr.p_Address[i];
			}
		}
		return *this;	//!!
	}

	T& operator[](int index)
	{
		return this->p_Address[index];
	}

	void push_back(const T & val)	//why const , T &
	{
		if (this->m_Capacity == this -> m_Size)
		{
			return;
		}
		this->p_Address[this->m_Size] = val;
		this->m_Size++;
	}

	void pop_back()
	{
		if (this->m_Size == 0)
		{
			return;
		}
		//this->p_Address[m_Size] = 0;
		this->m_Size--;
	}

	int getSize()
	{
		return this->m_Size;
	}

	int getCapacity()
	{
		return this->m_Capacity;
	}

	~MyArray()
	{
		if (p_Address != nullptr)
		{
			delete[] p_Address;	//[] ?
			p_Address = nullptr;
			this->m_Size = 0;
			this->m_Capacity = 0;
		}
	}

private:
	int m_Size;
	int m_Capacity;
	T *p_Address;
};
#pragma once
#include <iostream>
#include "main_basic.hpp"
#include <sstream>
using namespace std;

class Person
{
public:
	Person() {}
	Person(int mage, string mname) :age(mage), name(mname) {}
	int age;
	string name;
};

void Print(MyArray< Person>& arr)
{
	for (int i = 0; i < arr.getSize(); i++)
	{
		cout << arr[i].age <<  arr[i].name << " ";
	}
}


int main()
{
	MyArray< Person> array1(10);
	for (int i = 0; i < 10; i++)
	{
		std::ostringstream oss;
		oss << "张三" << i;
		std::string name = oss.str();
		Person p(i,name);
		array1.push_back(p);
	}
	cout << "array1打印输出:" << endl;
	Print(array1);

	cout << "array1 大小 " << array1.getSize() << endl;
	cout << "array1 容量 " << array1.getCapacity() << endl;

	MyArray< Person> array2(array1);
	cout << "array2打印输出:" << endl;
	Print(array2);

	cout << "array2 大小 " << array1.getSize() << endl;
	cout << "array2 容量 " << array1.getCapacity() << endl;
	array2.pop_back();
	cout << "array2 大小 " << array1.getSize() << endl;
	cout << "array2 容量 " << array1.getCapacity() << endl;

	return 0;
}
[holo@jiayinhao test]$ valgrind ./test
==26740== Memcheck, a memory error detector
==26740== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==26740== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==26740== Command: ./test
==26740== 
array1打印输出:
0张三0 1张三1 2张三2 3张三3 4张三4 5张三5 6张三6 7张三7 8张三8 9张三9 array1 大小 10
array1 容量 10
array2打印输出:
0张三0 1张三1 2张三2 3张三3 4张三4 5张三5 6张三6 7张三7 8张三8 9张三9 array2 大小 10
array2 容量 10
array2 大小 10
array2 容量 10
==26740== 
==26740== HEAP SUMMARY:
==26740==     in use at exit: 0 bytes in 0 blocks
==26740==   total heap usage: 22 allocs, 22 frees, 6,026 bytes allocated
==26740== 
==26740== All heap blocks were freed -- no leaks are possible
==26740== 
==26740== For lists of detected and suppressed errors, rerun with: -s
==26740== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值