内存知识:
C语言(计算机专业应该知道的内存知识)_学习&笔记的博客-CSDN博客
C语言(计算机专业应该知道的管理内存的数据结构)_学习&笔记的博客-CSDN博客_操作系统实现内存管理常用的数据结构
C语言为内存分配空间(代码段、数据段、bss段、存储类、变量的生命周期)_学习&笔记的博客-CSDN博客_内存代码段和数据段
1.内存溢出与内存泄漏
内存溢出:内存溢出 OOM (out of memory),是指程序在申请内存时,没有足够的内存空间供
其使用,出现out of memory;比如申请了一个int,但给它存了long才能存下的数,那就是内存溢
出。
内存泄漏:对于C++的内存泄漏,总结一句话:就是new出来的内存没有通过delete合理的释放
掉!
2.内存泄漏出现的情况总结
NO1: 程序循环new创建出来的对象没有及时的delete掉,导致了内存的泄露。
#include <iostream>
#include <new.h>
using namespace std;
void out_of_memroy()
{
cout << "ERROR:内存已耗尽!" << endl;
}
int main()
{
set_new_handler(out_of_memroy);//注意参数传递的是函数的地址;
while(1)
{
new int[1000];
}
return 0;
}
以上代码会在堆区疯狂的动态分配内存空间,导致系统内存耗尽时自动调用set_new_handler参数列表中的函数,打印出ERROR:内存已耗尽!
NO2: 指针重新赋值导致内存泄漏
char * p = (char *)malloc(10);
char * np = (char *)malloc(10);
其中,指针变量 p 和 np 分别被分配了 10 个字节的内存。
p=np;
这时候,指针变量 p 被 np 指针重新赋值,其结果是 p 以前所指向的内存位置变成了孤立的内存。
它无法释放,因为没有指向该位置的引用,从而导致 10 字节的内存泄漏。
NO3: 错误的内存释放导致内存泄漏
假设有一个指针变量 p,它指向一个 10 字节的内存位置。该内存位置的第三个字节又指向某个动
态分配的 10 字节的内存位置。
free(p);
很显然,如果通过调用 free 来释放指针 p,则 np 指针也会因此而变得无效。np 以前所指向的内
存位置也无法释放,因为已经没有指向该位置的指针。换句话说,np 所指向的内存位置变为孤立
的,从而导致内存泄漏。
改正:
free(p->np);
free(p);
NO4: new创建了一组对象数组,内存回收的时候却只调用了delete而非delete []来处理导致内存泄
漏。
class Object1
{
int a;
int b;
};
int main() {
Object1* arry1 = new Object1[100];//创建包含100个Object1的对象数组arry1并返回数组首地址;
Object1* arry2 = new Object1[100];//创建包含100个Object1的对象数组arry2并返回数组首地址;
delete []arry1;//回收了数组arry1里的所有对象动态创建时占用的内存空间;
delete arry2;//回收了数组arry2里的第一个对象动态创建时占用的内存空间,导致其他99个对象的内存空间泄露;
cout << "Press any key to continue... ..." << endl;
getchar();
return 0;
}
NO5:双指针释放错误,存在指针释放的遗漏。
如例子正确的释放一个双指针。
Void FunRightA()
{
Char **p = new char*[10];
For(int i=0;i<10;i++)
{
p[i] = new char[10];
}
If(p!=nullptr)
{
For(int i=0;i<10;i++)
{ Delete []p[i];
p[i] = nullptr;
}
Delete []p;
p = nullptr;
}
}
3.如何避免内存泄露
- 确保没有在访问空指针。
- 每个内存分配函数都应该有一个
free
函数与之对应,alloca
函数除外。 - 每次分配内存之后都应该及时进行初始化,可以结合 memset 函数进行初始化,calloc 函数除外。
- 每当向指针写入值时,都要确保对可用字节数和所写入的字节数进行交叉核对。
- 在对指针赋值前,一定要确保没有内存位置会变为孤立的。
- 每当释放结构化的元素(而该元素又包含指向动态分配的内存位置的指针)时,都应先遍历子内存位置并从那里开始释放,然后再遍历回父节点。
- 始终正确处理返回动态分配的内存引用的函数返回值。
4.内存泄露检测工具valgrind
这是一个linux下的内存泄露检测工具
内存泄露情况:
无内存泄露情况: