关于C++ delete 来释放new分配的内存

一般在C语言中我们使用malloc和free进行内存分配和释放,但是在C++中增加了一个新的
new和delete 操作来进行,按照C++的说法delete是释放内存但是指针得到保留,防止内存
泄露,并且NEW和DELETE要成对出现。我们知道指针本生也是一个保存在内存中某个位置的变量,
如果释放了内存我们是否可以考虑为其中的值得到了删除,而指针自身可以再次指向其他的值?
而还有一点我们需要明白使用NEW分配的内存是HEAP而变量的赋值是栈,

在OS中我们大概可以理解如下(32位系统为例),我这里的共享是指线程是否共享:

4G
     kernel --内核内存
3G   text --代码文本 共享
     data --初始化的全局变量和静态变量 共享
     dss  --未始化的全局变量和静态变量 共享
     栈   --级动态变量数组等 不共享
     堆   --malloc 共享
0    共享库 --库文件 mmap 映射 共享

可以看到栈和堆不是一个区域,并且栈始终是自我释放的遵循后入先出原则

我们接下来用如下的小程序带上GDB进行调试

  8 #include
  9 using namespace std;
 10 
 11 
 12 int main(void)
 13 {
 14     int *p;  //一个不初始化的指针,不能使用*p=一个INT数字,只能赋予一个指针变量p=(init *)0x130000表示p指针指向130000位置
 15     short *b  = new short;
 16     short *c = new short;
 17 
 18     *b=0X128;
 19 
 20     cout<<"noinit int address is :"<< p <<" "<<sizeof(*p)<<endl;
 21     cout<<"short b address is :"<< b <<" "<<sizeof(*b)<<"\n";
 22     cout<<"short c address is :"<< c <<" "<<sizeof(*c)<<endl;
 23     delete b; //成对出现
 24     delete c;
 25     //DELETE不释放指针只是释放内存,那么指针指向的内存可以用于其他用途
 26     cout<<"init int address is :"<< b <<" "<<sizeof(*b)<<"\n";
 27     cout<<"noinit dou address is :"<< c <<" "<<sizeof(*c)<<endl;
 28 
 29     *b=0X256; //直接赋予值,赋值成功
 31     delete b; //不成对出现
 32     *b=0X512; //便于观察而已
 33     delete b; //便于观察,避免指针释放  
  }
~ 如果我们在
 23     delete b;      
 后去GDB *b的只为0那么说明delete起到了效果             
 gdb ./a.out 
(gdb) b 23
Breakpoint 1 at 0x400a79: file pointer2.cpp, line 23.
(gdb) r

Breakpoint 1, main () at pointer2.cpp:23
23              delete b;
(gdb) p b
$1 = (short *) 0x602010
(gdb) x/2xh 0x602010 
0x602010:       0x0128  0x0000
可以看到当前为0X0128数据在这个存储2个字节里面我是也就是0x602010 0x602011
(gdb) n
24          delete c;
(gdb) x/2xh 0x602010
0x602010:       0x0000  0x0000
这里跑完了delete b;  可以看到数据没有了在内存中,继续
继续向下

29              *b=0X256;
(gdb) n
30          delete b;
(gdb) p b
$3 = (short *) 0x602010
这里跑完了 *b=0X256;但是指针位置没有变化,也就是DELETE后指针得到了保留
继续
(gdb) p *b
$4 = 598
(gdb) x/2xh 0x602010
0x602010:       0x0256  0x0000

可以看到数据没有问题。继续看看是否能DELETE
(gdb) n
(gdb) x/2xh 0x602010
0x602010:       0x2020  0x0060
可以看到delete并没有删除数据而已弄了一些垃圾数据进来。
其实这个程序直接跑会报错
*** Error in `./a.out': double free or corruption (fasttop): 0x0000000000f1f010 ***
Aborted (core dumped)
用GDB只是为了找到原因

所以我们必须new和delete 成对使用,否者结果是不确定的,对空指针delete是安全的
delete后指针是得到了保留的没有问题,如果是动态数组将不能使用sizeof来确定他的长度
指针我感觉是使用的栈,同时在函数结束时自我释放。

附带关于GDB的内存查看
转自:http://www.cnblogs.com/super119/archive/2011/03/26/1996125.html

格式: x /nfu

说明
x 是 examine 的缩写

n表示要显示的内存单元的个数

f表示显示方式, 可取如下值
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
i 指令地址格式
c 按字符格式显示变量。
f 按浮点数格式显示变量。

u表示一个地址单元的长度
b表示单字节,
h表示双字节,
w表示四字节,
g表示八字节

Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),
t(binary), f(float), a(address), i(instruction), c(char) and s(string).
Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes)

举例
x/3xh buf
表示从内存地址buf读取内容,
h表示以双字节为一个单位,
3表示三个单位,
x表示按十六进制显示

</sizeof(*c)<<endl;
</sizeof(*b)<<"\n";
</sizeof(*c)<<endl;
</sizeof(*b)<<"\n";
</sizeof(*p)<<endl;

时间: 2024-10-28 21:45:36

关于C++ delete 来释放new分配的内存的相关文章

内存分配-c++类的对象中分配的内存的内存能不能在在程序中间delete掉再重新分配?

问题描述 c++类的对象中分配的内存的内存能不能在在程序中间delete掉再重新分配? Matrix& Matrix::operator=(const Matrix &mp) { if (mp.row_n != row_n||mp.column_n != column_n) { std::cout << ""Error size not match"" << std::endl; return this; }/ for (in

使用new时分配的内存为什么总是上一个释放的内存

问题描述 使用new时分配的内存为什么总是上一个释放的内存 两次调用的时候分配的内存都一样 而且多次运行虽然每次都不一样 但是两次调用的内存都一样 这是什么原因 解决方案 c++ 用指针使用函数中new的内存块,用完释放 解决方案二: 系统本来就会做内存回收重用

c++-malloc、free、new、delete之间的关系,动态内存原理?

问题描述 malloc.free.new.delete之间的关系,动态内存原理? 想问的有很多,比如:堆的本质是什么?是一个类似指针链表的东西吗? 当[new int [100]]时,这个数组的内存地址是不是连续的一大整块?如果不连续,那么分配的时候又是如何跳跃的? 在delete这个数组时,编译器怎么知道要删除的内存有多大,删除完A地址后,编译器又怎么知道下一个要删除的是B地址? 还有,new []和delete可以配套使用吗? 解决方案 楼主请进传送门:http://www.perfect-

初学者求教,c++中new如何分配数组内存

问题描述 初学者求教,c++中new如何分配数组内存 c++中使用new定义动态数组时,如果数组大小已知,那么会如何分配内存?是在程序运行时按照使用的元素数分配还是按照数组大小一次性分配(和普通数组一样的方式) 解决方案 也是一次性分配,你可以自己测试下,申请完,看它的大小 解决方案二: C++ new内存分配 解决方案三: 运行时肯定已经知道数组的大小了,数组多大就分配多大的内存. 解决方案四: 都可以的. 如果要分配的大小比较大的话,建议用new new还需要你delete,是在堆分配空间

new-如何释放堆的部分内存

问题描述 如何释放堆的部分内存 int *p*q;p=new int[10];q = P+5;delete q;//如何只释放P+5 以后的内存? 解决方案 一般来说堆分配器分配一块内存时会在这块内存的头部或者尾部保存一些信息(包括这块内存的大小和指向其他内存块的指针)释放一块堆内存时需要先找到之前保存的信息. 还没有见过可以部分释放一块堆内存一般都是整块释放. 但从技术上是可以实现的. 我之前写过一个简单的堆分配器基本原理如上可以参考一下:http://blog.csdn.net/ce123_

C++ 静态成员变量 嵌套类分配回收内存

嵌套类分配回收内存: #include <stdio.h> #include <assert.h> class CA { public: inline static CA *GetInstance(void) { assert(m_instance != NULL): return m_instance; } void Print(void) { puts("主类的Print函数运行看看"): } class Garbage//用来分配内存的嵌套类 { publ

释放动态申请数组内存-C++中动态申请的数组内存异常时内存释放问题

问题描述 C++中动态申请的数组内存异常时内存释放问题 在C++的一个方法中动态申请了一段数组的内存,还未通过delete[] 语句释放这段内存,方法异常,此时代码不会执行后面的delete[] 语句了,那么前面申请的这段数组内存怎么释放? C++中的auto_prt只支持单个对象动态内存的管理,对于数组动态申请的内存怎么管理? 解决方案 应该在运行期系统自动帮你归还,前提是你的数组是由class构成,但不是内置类型.详见EFFECTIVE C++第三版条款52(写了placement new也

内存分配与内存对齐全面探讨

转自:http://blog.csdn.net/cuibo1123/article/details/2547442 引言 操作系统的内存分配问题与内存对齐问题对于低层程序设计来说是非常重要的,对内存分配的理解直接影响到代码质量.正确率.效率以及程序员对内存使用情况.溢出.泄露等的判断力.而内存对齐是常常被忽略的问题,理解内存对齐原理及方法则有助于帮助程序员判断访问非法内存. 程序的内存分配问题 一般C/C++程序占用的内存主要分为5种 1.栈区(stack):类似于堆栈,由程序自动创建.自动释放

new生成变量不释放是否会造成内存泄露

问题描述 new生成变量不释放是否会造成内存泄露 MFC中的对话框初始化函数有以下代码, 其中用new生成的东西,不释放是否会造成内存泄露? 如果会造成内存泄露,改怎样处理? 好多书上经常这么用,也没看到在哪里释放了. HDITEM item; item.cxy=200; item.mask=HDI_WIDTH; m_propertyGrid.GetHeaderCtrl().SetItem(0, new HDITEM(item)); CMFCPropertyGridProperty *pProp