如何在linux下检测内存泄漏
1个回答
展开全部
linux操作系统应用专区
1.开发背景:
在
windows
下使用
vc
编程时,我们通常需要
debug
模式下运行程序,而后调试器将在退出程序时,打印出程序运行过程中在堆上分配而没有释放的内存信息,其中包括代码文件名、行号以及内存大小。该功能是
mfc
framework
提供的内置机制,封装在其类结构体系内部。
在
linux
或者
unix
下,我们的
c++
程序缺乏相应的手段来检测内存信息,而只能使用
top
指令观察进程的动态内存总额。而且程序退出时,我们无法获知任何内存泄漏信息。为了更好的辅助在
linux
下程序开发,我们在我们的类库项目中设计并实现了一个内存检测子系统。下文将简述
c++
中的
new
和
delete
的基本原理,并讲述了内存检测子系统的实现原理、实现中的技巧,并对内存泄漏检测的高级话题进行了讨论。
2.new和delete的原理
当我们在程序中写下
new
和
delete
时,我们实际上调用的是
c++
语言内置的
new
operator
和
delete
operator。所谓语言内置就是说我们不能更改其含义,它的功能总是一致的。以
new
operator
为例,它总是先分配足够的内存,而后再调用相应的类型的构造函数初始化该内存。而
delete
operator
总是先调用该类型的析构函数,而后释放内存(图1)。我们能够施加影响力的事实上就是
new
operator
和
delete
operator
执行过程中分配和释放内存的方法。
new
operator
为分配内存所调用的函数名字是
operator
new,其通常的形式是
void
*
operator
new(size_t
size);
其返回值类型是
void*,因为这个函数返回一个未经处理(raw)的指针,未初始化的内存。参数
size
确定分配多少内存,你能增加额外的参数重载函数
operator
new,但是第一个参数类型必须是
size_t。
delete
operator
为释放内存所调用的函数名字是
operator
delete,其通常的形式是
void
operator
delete(void
*memorytobedeallocated);它释放传入的参数所指向的一片内存区。
这里有一个问题,就是当我们调用
new
operator
分配内存时,有一个
size
参数表明需要分配多大的内存。但是当调用
delete
operator
时,却没有类似的参数,那么
delete
operator
如何能够知道需要释放该指针指向的内存块的大小呢?答案是:对于系统自有的数据类型,语言本身就能区分内存块的大小,而对于自定义数据类型(如我们自定义的类),则
operator
new
和
operator
delete
之间需要互相传递信息。
当我们使用
operator
new
为一个自定义类型对象分配内存时,实际上我们得到的内存要比实际对象的内存大一些,这些内存除了要存储对象数据外,还需要记录这片内存的大小,此方法称为
cookie。这一点上的实现依据不同的编译器不同。(例如
mfc
选择在所分配内存的头部存储对象实际数据,而后面的部分存储边界标志和内存大小信息。g++
则采用在所分配内存的头
4
个自己存储相关信息,而后面的内存存储对象实际数据。)当我们使用
delete
operator
进行内存释放操作时,delete
operator
就可以根据这些信息正确的释放指针所指向的内存块。
以上论述的是对于单个对象的内存分配/释放,当我们为数组分配/释放内存时,虽然我们仍然使用
new
operator
和
delete
operator,但是其内部行为却有不同:new
operator
调用了operator
new
的数组版的兄弟-
operator
new[],而后针对每一个数组成员调用构造函数。而
delete
operator
先对每一个数组成员调用析构函数,而后调用
operator
delete[]
来释放内存。需要注意的是,当我们创建或释放由自定义数据类型所构成的数组时,编译器为了能够标识出在
operator
delete[]
中所需释放的内存块的大小,也使用了编译器相关的
cookie
技术。
1.开发背景:
在
windows
下使用
vc
编程时,我们通常需要
debug
模式下运行程序,而后调试器将在退出程序时,打印出程序运行过程中在堆上分配而没有释放的内存信息,其中包括代码文件名、行号以及内存大小。该功能是
mfc
framework
提供的内置机制,封装在其类结构体系内部。
在
linux
或者
unix
下,我们的
c++
程序缺乏相应的手段来检测内存信息,而只能使用
top
指令观察进程的动态内存总额。而且程序退出时,我们无法获知任何内存泄漏信息。为了更好的辅助在
linux
下程序开发,我们在我们的类库项目中设计并实现了一个内存检测子系统。下文将简述
c++
中的
new
和
delete
的基本原理,并讲述了内存检测子系统的实现原理、实现中的技巧,并对内存泄漏检测的高级话题进行了讨论。
2.new和delete的原理
当我们在程序中写下
new
和
delete
时,我们实际上调用的是
c++
语言内置的
new
operator
和
delete
operator。所谓语言内置就是说我们不能更改其含义,它的功能总是一致的。以
new
operator
为例,它总是先分配足够的内存,而后再调用相应的类型的构造函数初始化该内存。而
delete
operator
总是先调用该类型的析构函数,而后释放内存(图1)。我们能够施加影响力的事实上就是
new
operator
和
delete
operator
执行过程中分配和释放内存的方法。
new
operator
为分配内存所调用的函数名字是
operator
new,其通常的形式是
void
*
operator
new(size_t
size);
其返回值类型是
void*,因为这个函数返回一个未经处理(raw)的指针,未初始化的内存。参数
size
确定分配多少内存,你能增加额外的参数重载函数
operator
new,但是第一个参数类型必须是
size_t。
delete
operator
为释放内存所调用的函数名字是
operator
delete,其通常的形式是
void
operator
delete(void
*memorytobedeallocated);它释放传入的参数所指向的一片内存区。
这里有一个问题,就是当我们调用
new
operator
分配内存时,有一个
size
参数表明需要分配多大的内存。但是当调用
delete
operator
时,却没有类似的参数,那么
delete
operator
如何能够知道需要释放该指针指向的内存块的大小呢?答案是:对于系统自有的数据类型,语言本身就能区分内存块的大小,而对于自定义数据类型(如我们自定义的类),则
operator
new
和
operator
delete
之间需要互相传递信息。
当我们使用
operator
new
为一个自定义类型对象分配内存时,实际上我们得到的内存要比实际对象的内存大一些,这些内存除了要存储对象数据外,还需要记录这片内存的大小,此方法称为
cookie。这一点上的实现依据不同的编译器不同。(例如
mfc
选择在所分配内存的头部存储对象实际数据,而后面的部分存储边界标志和内存大小信息。g++
则采用在所分配内存的头
4
个自己存储相关信息,而后面的内存存储对象实际数据。)当我们使用
delete
operator
进行内存释放操作时,delete
operator
就可以根据这些信息正确的释放指针所指向的内存块。
以上论述的是对于单个对象的内存分配/释放,当我们为数组分配/释放内存时,虽然我们仍然使用
new
operator
和
delete
operator,但是其内部行为却有不同:new
operator
调用了operator
new
的数组版的兄弟-
operator
new[],而后针对每一个数组成员调用构造函数。而
delete
operator
先对每一个数组成员调用析构函数,而后调用
operator
delete[]
来释放内存。需要注意的是,当我们创建或释放由自定义数据类型所构成的数组时,编译器为了能够标识出在
operator
delete[]
中所需释放的内存块的大小,也使用了编译器相关的
cookie
技术。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询
广告 您可能关注的内容 |