常见动态内存错误---内存泄漏

常见动态内存错误

编译器不能自动发现动态内存错误,动态内存错误通常只能在程序运行时才能被捕捉到,而且错误原因不容易查找,错误本身也不容易捕捉,改错难度较大。

1.动态内存分配失败却继续操作

内存不足等有可能导致动态内存分配失败,所以使用new请求分配动态内存后一定要检查返回地址是否为NULL。

如用if(p==NULL) 或 if(p!=NULL)进行检查,未检查前不要操作动态内存空间。

2.动态内存空间未初始化就进行读操作

C++标准并未规定动态内存空间的默认值,程序无法预知该默认值的具体指。因此,未经初始化的动态内存空间可能持有一个不确定的值。

所以申请分配动态内存空间的同时,要初始化该动态内存空间,尽量不要使用系统默认值。

3.动态内存空间越界使用

指针的功能虽然很强,但它容易指向错误的地方。当指针指向不正确的数据类型时,指针操作就会出错。

尤其是当指针指向一个数组时,很容易越界,造成错误。

4.内存泄漏

内存泄漏是一种比较严重的动态内存错误。程序长时间运行最终可能导致内存耗尽,运行速度变慢甚至系统奔溃。

例如:new与delete使用不配对,就可能导致new的空间未被delete。

使用new运算符申请分配的内存空间使用完后,一定要记得使用delete释放,且new形式要与delete对应。

5.继续使用已经释放了的动态内存空间

执行delete后,相应的指针变量的值未被改变,它依然指向原来的动态内存空间,只是原来动态内存空间的内容已经毫无意义了。

所以在执行delete之后,通常要将指针变量的值置成NULL,以免对内存空间进行误操作或者无效操作。

下面具体讲讲内存泄漏:

内存泄漏

指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。

内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费。

下面举几个例子:

1.下面a先是申请了一个int型的动态内存空间,初始化值为12,后面a又申请了一个int型空间,初始化值为34,

则第一次存储12的空间就不会被释放,并且存储12的空间没有被释放,也不能被使用了,造成了内存泄漏。

#include<iostream>
using namespace std;

int main()
{
	int *a=new int (12);

	cout<<*a<<endl;
	         //需要 delete a;
	a=new int (34);

	cout<<*a<<endl;

	delete a;

	system("pause");
	return 0;
}

2.下面的函数,当调用时,会在动态内存中创建一个char型数组,并在桟中生成一个char型指针变量pChar,用pChar指向该数组。

当F调用结束时,pChar会自动消失,因为它位于桟区中,是局部变量;

而长度为100的动态内存空间中的字符串数组却依然存在,没有释放。

所以退出F()后内存就泄漏了,而且每次调用都会造成新的泄漏。

void F(void)
{
	char *pChar=new char [100];
	//do something
}

最好的做法就是:

void F(void)
{
	char *pChar=new char [100];
	//do something

	delete []pChar;
}

3.出现以下问题呢?

//F返回一个指针,指向一个动态分配的对象
int *F(T arg)
{
   return new int [arg];//调用者负责释放此内存
}

返回指向动态内存的指针的函数给其调用者增加了一个额外的负担---调用者必须记得释放内存。

4.delete只提供了有限的保护

看下面的例子:

执行delete后,相应的指针变量的值未被改变,它依然指向原来的动态内存空间,只是原来动态内存空间的内容已经毫无意义了。

所以在执行delete之后,通常要将指针变量的值置成NULL,以免对内存空间进行误操作或者无效操作。

但是,

int *p=new int (42);
auto q=p;
delete p;
p=NULL;

p和q指向相同的动态分配的对象,我们delete此内存,然后将p置为NULL,指出它不再指向任何对象。但是,重置p对q没有任何作用,在我们释放p所指向的(同时也是q所指向的)内存时,q也变得无效了。在实际系统中,查找指向相同内存的所有指针是异常困难的。

时间: 2024-12-23 17:13:07

常见动态内存错误---内存泄漏的相关文章

C语言常见内存错误

C语言指针和内存泄露 常见的内存错误: 1.      内存分配未成功却使用了它. 如果指针p是函数的参数,要在函数的入口处用assert(p!=NULL)进行检查: 如果是用malloc来动态申请内存,应该用if(p==NULL)或if(p!=NULL)进行防错处理. 2.      内存分配成功,尚未初始化就使用它. 3.      内存分配成功并且初始化,但操作越界. 例如在使用数组时经常发生"多1"或"少1"操作. 4.      忘记释放内存造成内存泄露.

C语言中常见的内存错误与解决方法

常见的错误 关于内存的一些知识已在内存分配中提及,现记录与分享常见的内存错误与对策. 类型 1:内存未分配成功,却使用了它. 方   法:在使用之前检查指针是否为NULL. 1)当指针p是函数的参数时,在函数入口处用语句assert(p!=NULL)进行断言检查. 2)当使用malloc或new来申请内存时,应该用if(p != NULL)进行防错检查. 类型 2:引用了尚未初始化的指针 原   因:内存的缺省初始值究竟是什么并没有统一的标准,在使用之前都进行初始化. 1)没有初始化的观念. 2

常见的C语言内存错误及对策(转)

http://see.xidian.edu.cn/cpp/html/483.html 一.指针没有指向一块合法的内存 定义了指针变量,但是没有为指针分配内存,即指针没有指向一块合法的内存.浅显的例子就不举了,这里举几个比较隐蔽的例子. 1.结构体成员指针未初始化 struct student {    char *name;    int score; }stu,*pstu; intmain() {    strcpy(stu.name,"Jimy");    stu.score =

大内高手—常见内存错误

转自:http://blog.chinaunix.net/uid-23228758-id-4355524.html 随着诸如代码重构和单元测试等方法引入实践,调试技能渐渐弱化了,甚至有人主张废除调试器.这是有道理的,原因在于调试的代价往往太大了,特别是调试系统集成之后的BUG,一个BUG花了几天甚至数周时间并非罕见. 而这些难以定位的BUG基本上可以归为两类:内存错误和并发问题.而又以内存错误最为普遍,即使是久经沙场的老手,也有时也难免落入陷阱.前事不忘,后世之师,了解这些常见的错误,在编程时就

常见内存错误的几点总结

学习C语言以来一直没有注意到细节的控制,敲代码总是"无所顾忌"的.如今慢慢把程序写大写复杂了.在资源宝贵和的嵌入式中.这个问题越来越须要注意了--内存的管理..让编程慢慢走上正轨,慢慢走上可预见性吧,慢慢与机器融为一体,慢慢习惯于如梁肇新前辈所说以机器的思维方式思维吧!!! 1.返回局部变量地址将引起内存错误 2.暂时空间过大:操作系统在载入某个应用程序时,都将为其分配一定大小的栈空间,若申请过大的局部变量.可能会引起栈溢出问题. (PC机上Windows和Linux系统一般不必操心这

[草稿][C语言][内存分配]常见内存错误

1. 使用未分配成功的内存 解决案: ①在使用内存前检查指针是否为NULL ②参数是指针时,在函数入口处用assert进行判断 ③如果指针指向动态申请的内存,用if进行容错处理 2. 使用分配成功,但未初始化的内存 解决案: ①定义数组后一定要初始化 3. 内存泄漏 解决案: ①new/malloc和delete/free一定要成对出现 4. 使用已被释放的内存 解决按: ①不要返回指向栈内存的指针或引用 ②释放内存后,将指针置为NULL

C++基础:二维数组动态的申请内存和释放内存

使用二维数组的时候,有时候事先并不知道数组的大小,因此就需要动态的申请内存.常见的申请内存的方法有两种:malloc/free 和 new/delete. 一.malloc/free (1)申请一维数组 void dynamicCreate1Array() { int m; int i; int *p; cout<<("please input the length of data:"); cin >> m; p = (int*)malloc(sizeof(in

iOS开发 两个内存错误的一般处理方法

本文转载至 http://blog.sina.com.cn/s/blog_a843a8850101dxlj.html 由于iOS5.0之前没有自动应用计数机制,也没有Java那样的垃圾回收功能.我们都需要自己管理和控制对象的回收,这是一件很麻烦的事情,也是做iOS项目中最容易出现的问题.如果不掌握这些方法,调试这些问题几乎没有头绪. 1.EXC_BAD_ACCESS内存错误与NSZombieEnabledEXC_BAD_ACCESS是最常见的错误了,这个一般是访问了释放了的内存地址空间造成的.比

关于ios 里面碰到内存错误的两种设置

1.EXC_BAD_ACCESS内存错误与NSZombieEnabled EXC_BAD_ACCESS是最常见的错误了,这个一般是访问了释放了的内存地址空间造成的.比如一个对象已经dealloc了,如果你仍向这个对象发 送消息,就会出现这个错误.由于出现这个错误时,几乎不显示什么有用的信息,我们根本无法确定程序错在何处.使用NSZombieEnabled环境变量 可以很好的解决这个问题. 打开你的工程,选择菜单“Product->Edit Scheme”或快捷键“Commend+<” NSZo