动态分配数组并且对指针进行运算后为什么不能释放内存?

hfrx001 2011-05-11 03:00:46
#include <iostream>

using namespace std;

int main()
{
//常规测试
double * p3 = new double [3];

p3[0] = 0.2;
p3[1] = 0.5;
p3[2] = 0.8;

cout<<"p3[0] = " <<p3[0] <<endl;
cout<<"p3[1] = " <<p3[1] <<endl;
cout<<"p3[2] = " <<p3[2] <<endl <<endl;

//指针加减测试
p3 += 1;

cout<<"p3[0] = " <<p3[0] <<endl;
cout<<"p3[1] = " <<p3[1] <<endl;

//释放动态数组
delete [] p3;

return 0;
}
请看“p3 +=1”和“delete [] p3”,这两条语句不能并存,并存的话编译是能通过,但是运行的时候,就“咚”的一声。
但把这两条语句随意注释其一就能正常运行,这是为什么啊?
...全文
206 23 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
D_B_Codd 2012-07-27
  • 打赏
  • 举报
回复
你在后面加个p3=p3-1就ok了
hfrx001 2011-05-12
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 tt2com 的回复:]

引用 20 楼 hfrx001 的回复:
另外我不释放在程序退出后会有什么后果?nwe出来的变量会一直赖在堆里只到系统重启?听说会造成内存泄漏,这块new的变量会随着时间变大溢出吗?

你不释放造成的内存泄露,就是说你的内存变少了。当然你写点小程序玩玩没什么问题。不过以后工作了,写程序就危险了
[/Quote]了解。
tt2com 2011-05-11
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 hfrx001 的回复:]
另外我不释放在程序退出后会有什么后果?nwe出来的变量会一直赖在堆里只到系统重启?听说会造成内存泄漏,这块new的变量会随着时间变大溢出吗?
[/Quote]
你不释放造成的内存泄露,就是说你的内存变少了。当然你写点小程序玩玩没什么问题。不过以后工作了,写程序就危险了
hfrx001 2011-05-11
  • 打赏
  • 举报
回复
另外我不释放在程序退出后会有什么后果?nwe出来的变量会一直赖在堆里只到系统重启?听说会造成内存泄漏,这块new的变量会随着时间变大溢出吗?
hfrx001 2011-05-11
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 bigshaby 的回复:]
引用 13 楼 hfrx001 的回复:
C/C++ code
delete [] (p3 - 3);
如果我偏移好多位还是这种好。

其实你这样也是不好的,一般做法是声明另一个指针(局部)记录数组地址,对数组操作的时候只用另外声明出来的这个指针,原来的那个不要用他,最后释放时只用原来的就行了。
[/Quote]
//指针加减测试
double * p4 = p3;
p4 += 1;

cout<<"p3[0] = " <<p4[0] <<endl;
cout<<"p3[1] = " <<p4[1] <<endl;

//释放动态数组
delete [] p3;
这么写代码有问题吗?
hfrx001 2011-05-11
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 zhao4zhong1 的回复:]
考虑一下我的忠告:

new和delete
以及
new type[...]和delete[]

fopen和fclose
那样用。

《深入解析Windows操作系统-Windows Internals》

计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)……
[/Quote]不懂...
BigShaby 2011-05-11
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 hfrx001 的回复:]
C/C++ code
delete [] (p3 - 3);
如果我偏移好多位还是这种好。
[/Quote]
其实你这样也是不好的,一般做法是声明另一个指针(局部)记录数组地址,对数组操作的时候只用另外声明出来的这个指针,原来的那个不要用他,最后释放时只用原来的就行了。
BigShaby 2011-05-11
  • 打赏
  • 举报
回复
把你的手想象成是p3,一开始你拿着自己的3块钱(数组)买东西自然没问题,但是现在你把自己的其中一块钱放下(p3+=1),伸手到别人腰包里拿另一块钱(系统的未分配给p3的内存),这时要花这一起的三块钱可就得问过对方让不让你花了。
赵4老师 2011-05-11
  • 打赏
  • 举报
回复
考虑一下我的忠告:

new和delete
以及
new type[...]和delete[]

fopen和fclose
那样用。

《深入解析Windows操作系统-Windows Internals》

计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
nightkids_008 2011-05-11
  • 打赏
  • 举报
回复
new里面调用的也是malloc你可以他里面维护着一个数据结构,你改了那个地址,这个结构信息就不对了。
hfrx001 2011-05-11
  • 打赏
  • 举报
回复
delete [] (p3 - 3);
如果我偏移好多位还是这种好。
tt2com 2011-05-11
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 hfrx001 的回复:]
另外问一下“double”不是8个字节的类型吗?为什么我“p3 += 1;”就一下从“p3[0]”跳过了8个字节到了“p3[1]”了呢?
[/Quote]
不管什么类型的指针都是4个字节的(当然和你的系统有关)
char* f;
double* f1;
f 和 f1 是一样大小的
hfrx001 2011-05-11
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 qq120848369 的回复:]
C/C++ code
delete [] --p3;
[/Quote]神人,这个方法代码量更少。
qq120848369 2011-05-11
  • 打赏
  • 举报
回复
delete [] --p3;
hfrx001 2011-05-11
  • 打赏
  • 举报
回复
    //释放动态数组
p3 -= 1;
delete [] p3;
如果我在释放前还原“p3”地址就可以正确释放而不用注释掉“p3 += 1;

”了,哇咔咔。
hfrx001 2011-05-11
  • 打赏
  • 举报
回复
另外问一下“double”不是8个字节的类型吗?为什么我“p3 += 1;”就一下从“p3[0]”跳过了8个字节到了“p3[1]”了呢?
hfrx001 2011-05-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 colorfulcode 的回复:]
动态分配的一块内村,在其前面都会有一个数据来描述这个内存块有多大,以便进行释放

而 执行了p3 += 1;之后,delete就找不到那个用于描述内存信息的数据了,因为p3的指向变了,所以...
[/Quote]你的意思是这样的吗?我动态分配数组时候在p3[0]地址的前面有一段数据来描述我分配的数组元素有多少,“double * p3 = new double [3];”就是把动态分配double数组的第0个元素的地址赋值给p3,但是我在后面把p3的地址也就是里面存储p3[0]的地址给变成了p3[1],当delete释放p3的时候,它首先要去找p3[0]前面的一块描述,来确定释放多少数组元素,由于我把p3弄成了p3[1],而p3[1]自然不可能有p3[0]前面的描述数据于是delete就释放失败了?
colorfulcode 2011-05-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 colorfulcode 的回复:]

动态分配的一块内村,在其前面都会有一个数据来描述这个内存块有多大,以便进行释放

而 执行了p3 += 1;之后,delete就找不到那个用于描述内存信息的数据了,因为p3的指向变了,所以...
[/Quote]

更正一下,不是找不到,而是找到的是不正确的数据
tt2com 2011-05-11
  • 打赏
  • 举报
回复
我不知道怎么理论化的告诉你,应该有告诉可以。不是你随便注释掉一句就没问题
而是只能注释掉p3 +=1 要不就内存泄露了。

至于为啥不能delete [](++p3);这个我从来没这个干过,但具体的理论不能这么干等待大牛解决下

个人感觉 delete []对应 new []
new []开辟的头地址应该会有一些基本的信息如大小,连接项指向下个地址。
delete[] 应该需要new[] 开辟内存大小的空间 你delete ++p3 使得大小信息没了才出错的吧

我是凭感觉说的啊,等待大牛说明下。
ryfdizuo 2011-05-11
  • 打赏
  • 举报
回复
delete [] p3是从p3开始起三个double指针。
delete [4] p3;
delete [16] p3;
delete [] p3;
这三种写法都一样,都只会释放3个double指针。p3加1,就会释放一个没有定义的double指针。
加载更多回复(3)

65,189

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧