内存空间与分配

1、内存分配错误

  动态内存分配错误有两种基本类型:内存错误和内存泄漏。

(1)内存错误

  当一个指针或者该指针所指向的内存单元成为无效单元,或者内存中分配的数据结构被破坏时,就会造成内存错误。指针未被初始化,指针被初始化为一个无效地址,指针被不小心错误地修改,在与指针相关联的内存区域被释放后使用该指针(这种指针被称为虚悬(dangling)指针),这些都会使指针变为无效指针。当通过一个错误指针或者虚悬指针对内存进行写入,或者将指针强制转换为不匹配的数据结构,又或者是写数据越界,内存自身也会遭到破坏。删除未被初始化的指针、删除非堆指针、多次删除同一指针或者覆盖一个指针的内部数据结构,都会造成内存分配系统错误。

(2)内存泄漏

  内存泄漏在被动态分配的内存没有被释放时产生。有许多情况会导致内存泄漏,如没有在程序的全部执行路径中释放内存,没有在析构函数中释放所有的内存等。一个程序在崩溃之前可运行的时间越长,则导致崩溃的原因与内存泄漏的关系越大。

  Windows会在程序结束的时候将泄漏的内存收回,因此内存泄漏是个暂时性的问题。但为什么必须消除内存泄露呢?首先,内存泄漏往往会导致系统资源的泄漏。动态分配内存往往不仅仅代表一块存储区域,还代表了某些类型的系统资源,如文件、窗口、设备上下文、GDI对象等。其次,高质量的程序和特定的服务器程序必须能够无限地运行下去。最后,内存泄漏往往是其他程序错误或不良编程习惯的征兆。

  导致内参泄漏的原因:忘记释放内存;构造函数失败;存在内存泄漏的析构函数;存在内存泄漏的异常处理程序;多个返回语句;使用错误形式的delete。

2、关于内存的初始化

  在调试版本里,堆里未被初始化的内存被0xCD字节模式填充,堆里释放的内存被0xDD字节模式填充。堆栈里被初始化的内存被0xCC字节模式填充。调试版本和发布版本里,未被初始化的全局内存都被初始化为0。

3、内存虚拟地址空间

  Windows使用一组固定的范围来分割进程的4GB虚拟地址空间,因此有时可通过查看指针的返回值来判断指针是否有效。

(1)Windows2000虚拟地址空间划分

0~0XFFFF(64KB):不能用来检测空指针赋值(访问冲突)

0x10000(64KB)~0x7FFEFFFF(2GB-64KB):Win32进程私有的(非保留的),用于程序代码和数据

0x7FFF0000(2GB-64KB)~0x7FFFFFFF(2GB):不能用来防止覆盖OS分区(访问冲突)

0x800000000(2GB)~0xFFFFFFFF(4GB):为操作系统保留,不可访问(访问冲突)

(2)Windows2000虚拟地址空间使用

0x00030000~0x0012FFFF:线程栈

0x00130000~0x003FFFFF:堆(有时堆位于此处)

0x00400000~0x005FFFFF:可执行代码

0x00600000~0x0FFFFFFF:堆(有时堆位于此处)

0x10000000~0x5FFFFFFF:App DLLs、Msvcrt.dll、Mfc42.dll

0x77000000~0xFFFFFFFF:Advapi32.dll、Comctl32.dll、Gdi32.dll、Kernel32.dll、Ntdll.dll、Rpcrt4.dll、Shell32.dll、User32.dll

其中,0x00400000是所有版本的Windows能使用的最低基地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值