| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4584 人关注过本帖
标题:[求助] 如果new了一个东西后,delete了两次会怎样?
只看楼主 加入收藏
cedricporter
Rank: 1
等 级:新手上路
帖 子:49
专家分:3
注 册:2007-2-6
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:10 
[求助] 如果new了一个东西后,delete了两次会怎样?
请问new了一个东西后,delete了两次会怎样?????

如:
int* ans = new int[100];
delete [] ans;
delete [] ans;


第一次delete后,如果ans指向的内存被其他东西占用,第二次delete会不会把后来其他程序占用的这段内存给释放了???

还有还有..第一次delete后,指针会指向什么地方....

引用一个人的程序/* Programe 2, by lily */
#include <iostream.h>
void main()
{
  int * p=new int[3];
  for (int i=0;i<3;i++) p[i]=i;
  delete []p;
  cout<<"p[0]="<<p[0]<<",p[1]="<<p[1]<<",p[2]="<<p[2]<<"\n";
  //ater p is delete,change the value of *p
  for (int j=0;j<3;j++) p[j]=j+100;
  cout<<"p[0]="<<p[0]<<",p[1]="<<p[1]<<",p[2]="<<p[2]<<"\n";
}
  结果还是出乎意料,*p的值居然还可以改变呢。结果是:
p[0]=-572662307,p[1]=-572662307,p[2]=-572662307
p[0]=100,p[1]=101,p[2]=102

为什么会这样???


-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
还有还有,
如果
int* ans[2];
ans[0] = new int[100];
ans[1] = new int[100][100];
ans[2] = new int[100][100][100];

应该怎么delete??

             谢谢~~

[[it] 本帖最后由 cedricporter 于 2009-8-2 11:43 编辑 [/it]]
搜索更多相关主题的帖子: delete 释放 new 
2009-08-02 11:12
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:5 
回复 楼主 cedricporter
delete再次我也不知道会怎么样,有空我再去查查吧。我想结果无外乎两种,要么是出现致命错误,程序终止。要么就是第二次什么也没干。

至于delete之后,那个指针其实还指着释放之间的位置。发生的变化只是现在的这个位置已经是一个不可引用的位置了而已。
当然这不可引用只是说应该不引用了,而不是真的不能用了。你自己用,也是可以的,系统可能不会查出这个错误。你问为什么p在再赋值之前会变成那个值,这是vc特有的一个性质。申请了没用的空间,和申请后释放的空间,它会分别赋上统一的值(分别是0x0c和0x0d我印象里)。所以p[0,1,2]都变成了相同的值,这是为了方便程序员调试时找内存错误用的。换句话说,如果你看见一个地方的值变成了上述那样,你就应该想到,这个地方出错了,你引用了一个已经释放了的空间。

当然如果你没能及时发现,又把它覆盖了,那就很可惜了。虽然可能这种小程序没什么影响,但这样做是很危险的。因为系统认为现在这个位置是空闲的,所以如果又有内存申请,就会拨出这个空间,给其它的程序或者是这个程序的其它部分用。这会导致数据错误。


第说的第二们问题,其实很简单,用过几次new就要用几次delete。只能一个个delete你申请的空间。
然后那个ans[2]是静态声明的,就不用delete了。
2009-08-03 13:18
CrystalFan
Rank: 8Rank: 8
来 自:江苏南京
等 级:蝙蝠侠
帖 子:187
专家分:802
注 册:2009-7-30
收藏
得分:5 
(1)delete 一次以后,p成了野指针,它作为地址的值还是有效地没还可以访问它以前指向的内存,不过那片内存被重新格式化了;
(2)p不等于NULL,用 if(p) 语句不能判断它指向的内存是否有效(此时它指向的内存无效,p本身有效);
(3)delete 一次以后,不能再次delete,否则会报错;
(4)此时如果误用p指针,仍然可以修改内存的值和从该处取出数值,但此时数据不受保护,该内存空间可能被重新被分配给别的变量;
(5)如果p指向的空间再次被new函数分配,即使是分配给别的指针,即使分配大小与原来不一样,p又恢复了效力,可以改变内存的值,甚至可以重新被delete,p的作用与新分配的指针一样;
程序例证:
程序代码:
#include<iostream>
using namespace std;
main()
{
    int *a;
    a=new int[3];
    a[0]=5;
    a[1]=6;
    a[2]=7;
    printf("a[0]=%d a[1]=%d a[2]=%d \na=%ld\n",a[0],a[1],a[2],a);

    delete a;
    printf("After delete a:\n");
    printf("a[0]=%d a[1]=%d a[2]=%d \na=%ld\n",a[0],a[1],a[2],a);

    a[0]=-1;
    a[1]=-2;
    printf("在给a指向的内存赋值以后:\n");
    printf("a[0]=%d a[1]=%d a[2]=%d \na=%ld\n",a[0],a[1],a[2],a);

    int *c=new int[4];
    c[0]=7;
    c[1]=8;
    c[2]=9;
    c[3]=100;
    printf("After define c:\n");
    printf("a[0]=%d a[1]=%d a[2]=%d \na=%ld\n",a[0],a[1],a[2],a);
    printf("c[0]=%d c[1]=%d c[2]=%d c[3]=%d\nc=%ld\n",c[0],c[1],c[2],c[3],c);

    a[0]=10;
    a[1]=11;
    printf("在给a指向的内存赋值以后:\n");
    printf("a[0]=%d a[1]=%d a[2]=%d \na=%ld\n",a[0],a[1],a[2],a);
    printf("c[0]=%d c[1]=%d c[2]=%d c[3]=%d\nc=%ld\n",c[0],c[1],c[2],c[3],c);

    delete a;
    printf("After define a:\n");
    printf("a[0]=%d a[1]=%d a[2]=%d \na=%ld\n",a[0],a[1],a[2],a);
    printf("c[0]=%d c[1]=%d c[2]=%d c[3]=%d\nc=%ld\n",c[0],c[1],c[2],c[3],c);
    return 0;
}


[[it] 本帖最后由 CrystalFan 于 2009-8-3 15:11 编辑 [/it]]
收到的鲜花
  • pangding2009-08-04 13:39 送鲜花  49朵   附言:乐于助人~~
2009-08-03 15:10
CrystalFan
Rank: 8Rank: 8
来 自:江苏南京
等 级:蝙蝠侠
帖 子:187
专家分:802
注 册:2009-7-30
收藏
得分:10 
第二个问题
你的定义是错的:
ans[0] = new int[100]; 是对的,ans[0]符合int*类型;
ans[1] = new int[100][100]; 是错的,new int[100][100]对应的应该是int**类型;
ans[2] = new int[100][100][100];也是错的,应该是int*** 类型;

如果你想表达的是:
int* a[2];
a[0]=new int[100];
a[1]=new int[200];
则应该是:
delete a[0];
delete a[1];

如果你想表达的是:
int** a;
a=new int*[2];
a[0]=new int[100];
a[1]=new int[200];
则释放顺序应该是:
delete a[0];
delete a[1];
delete a;
先释放a[i]指向的int*指针
如果先delete a;
那么a[0]和a[1]值就无效了,它们指向的内存空间就泄露(无法释放)了。
规律就是,释放时和原来定义的顺序真好相反(同级指针顺序可逆,如a[0]和a[1])。
2009-08-03 15:28
cedricporter
Rank: 1
等 级:新手上路
帖 子:49
专家分:3
注 册:2007-2-6
收藏
得分:0 
回复 4楼 CrystalFan
谢谢

[[it] 本帖最后由 cedricporter 于 2009-8-3 15:45 编辑 [/it]]

清脆的口琴聲﹏悠揚的旋律﹏然而︵每個音符︵?°都充滿了悲傷︵?°~↘
2009-08-03 15:41
CrystalFan
Rank: 8Rank: 8
来 自:江苏南京
等 级:蝙蝠侠
帖 子:187
专家分:802
注 册:2009-7-30
收藏
得分:0 
互相帮助,共同进步!
2009-08-03 22:36
金多虾
Rank: 2
等 级:论坛游民
帖 子:153
专家分:99
注 册:2009-6-9
收藏
得分:0 
会报错的吧,你上机试验一下不就行了,可以试试的
2009-08-04 05:38
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
回复 4楼 CrystalFan
嗯,说得比较清楚~

其实我不建议用new分配多维数组,语法本来就很奇怪,而且也没什么特别的实用价值。而且所谓分配的什么int***的也可以强转成int*。

new和delete的这些东西刚开始学的时候还是要小心些的好,争取不要出错。
有种观念不是说无知可以受到保护吗,就是说只学标准C或者C++的东西,其它的就当不知道。不要利用编译器的特性(当然其实实际编程的时候还是要用的,只是说初学的时候不要用),以便依赖这些性质,或者使你误以为这些性质就是C/C++语言本来就有的性质,没有就不对之类的。

楼主的问题问的比较细,显然也是自己研究过了。这种精神是可嘉的,要继续保持哟!!
当然 CrystalFan 回答的也很仔细,要保持~~ 嘿嘿
2009-08-04 13:38
cedricporter
Rank: 1
等 级:新手上路
帖 子:49
专家分:3
注 册:2007-2-6
收藏
得分:0 
回复 7楼 金多虾
那个好像会报错,貌似delete一个指针后再修改指针指向的值后,运行到最后编译器会报错.....

清脆的口琴聲﹏悠揚的旋律﹏然而︵每個音符︵?°都充滿了悲傷︵?°~↘
2009-08-04 15:14
cedricporter
Rank: 1
等 级:新手上路
帖 子:49
专家分:3
注 册:2007-2-6
收藏
得分:0 
回复 8楼 pangding
谢谢认真负责的版主~~

清脆的口琴聲﹏悠揚的旋律﹏然而︵每個音符︵?°都充滿了悲傷︵?°~↘
2009-08-04 15:15
快速回复:[求助] 如果new了一个东西后,delete了两次会怎样?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019366 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved