示例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)