new 一个数组,然后对数组pp越界访问,delete []pp 时出错,为什么?

时间:2022-11-30 02:29:24
new 一个数组,然后对数组pp越界访问,delete []pp 时出错,为什么?
 void main()
{
  int *pp=new int[3];

 *(pp+0)=0;
 *(pp+1)=1;
 *(pp+2)=2;

 *(pp+3)=3;
 cout<< "----- " <<   *(pp+0)<<   *(pp+1)<<   *(pp+2)<<   *(pp+3) <<endl;
 cout<< "----- " <<   *(pp+3)<<endl;

 //delete [] pp; 没有这句话时 程序可以正常结束

}

void main()
{
  int *pp=new int[3];

 *(pp+0)=0;
 *(pp+1)=1;
 *(pp+2)=2;

 *(pp+3)=3;
 cout<< "----- " <<   *(pp+0)<<   *(pp+1)<<   *(pp+2)<<   *(pp+3) <<endl;
 cout<< "----- " <<   *(pp+3)<<endl;

 delete [] pp;//程序运行到这里时会出错 为什么呢?编译器是怎么做的?

}

37 个解决方案

#1


偶用的是vc6

#2


偶感觉可能程序要释放*(pp+3)处的内存,所以导致错误吧。
再深层的原因不知了。

顶一下

#3


明明知道是错了还要这么用

#4


内存中可以看到初始化为 CD CD CD CD CD CD CD CD CD CD CD CD FD FD FD FD (在第一个CD前也有 FD FD FD FD)
 0xFD( deFencde Data ) 初始化受保护的内存(debug 版在动态分配内存的前后加入保护内存以防止越界访问)
而你的 *(pp+3)=3; 正好把 FD FD FD FD 这改为了03 00 00 00 ,应该是删除这的时候导致出错

#5


delete [] pp;//程序运行到这里时会出错 为什么呢?编译器是怎么做的?
delete与[]之间没有空格吧?

#6


应该是没有空格的缘故

#7


weixing979(★★★闪电侠★★★) 正解
我在VC里F5调试你的程序,DEBUG记录里有这么一段:
memory check error at 0x00371EDC = 0x03, should be 0xFD.
memory check error at 0x00371EDD = 0x00, should be 0xFD.
memory check error at 0x00371EDE = 0x00, should be 0xFD.
memory check error at 0x00371EDF = 0x00, should be 0xFD.

#8


我发现把这句:
 *(pp+3)=3;
注释掉就没不会有错误了

莫非delete删除的空间范围是编译器根据你访问的范围来决定释放范围的?

#9


饿,果然如weixing979(★★★闪电侠★★★)所说,跟踪的话会发现错误是发生在*(pp+3)=3;
而不是delete那里

#10


才new了3个,现在要delete 4个
不出错才怪呢

#11


觉得weixing979(★★★闪电侠★★★) 的有理!

#12


mark

#13


mark

#14



诸位是如何在vc下查看内存分布的啊?

#15


先在某行打上断点,然后F5,调试时 View -- Debug Windows -- Memory

#16


多谢诸位的指点,刚才也和同学讨论了一下,也看了内存分布,总算明白了一些。

void main()
{
int *pp=new int[3];
//内存分布:
// (受保护的内存标志)   pp                                      (受保护的内存标志)
//      |               |                                        |
//      FD FD FD FD    CD CD CD CD   CD CD CD CD   CD CD CD CD   FD FD FD FD


*(pp+0)=0;
// (受保护的内存标志)   pp                                      (受保护的内存标志)
//      |               |                                        |
//      FD FD FD FD    00 00 00 00   CD CD CD CD   CD CD CD CD   FD FD FD FD


*(pp+1)=1;
// (受保护的内存标志)   pp                                      (受保护的内存标志)
//      |               |                                        |
//      FD FD FD FD    00 00 00 00   01 00 00 00   CD CD CD CD   FD FD FD FD


*(pp+2)=2;
// (受保护的内存标志)   pp                                      (受保护的内存标志)
//      |               |                                        |
//      FD FD FD FD    00 00 00 00   01 00 00 00   02 00 00 00   FD FD FD FD


*(pp+3)=3;
// (受保护的内存标志)   pp                                      
//      |               |                                        
//      FD FD FD FD    00 00 00 00   01 00 00 00   02 00 00 00   03 00 00 00


cout<< "----- " << *(pp+0)<< *(pp+1)<< *(pp+2)<< *(pp+3) <<endl;
cout<< "----- " << *(pp+3)<<endl;

delete [] pp;//程序运行到这里时会出错 为什么呢?编译器是怎么做的?
// (受保护的内存标志)   pp                                      
//      |               |                                        
//      FD FD FD FD    00 00 00 00   01 00 00 00   02 00 00 00   03 00 00 00

只找到了“受保护的内存标志”的起始位置,另外一个“受保护的内存标志”找不到了。
应该是因此而出错的吧

#17


晕 格式全乱了! 再整理一下
多谢诸位的指点,刚才也和同学讨论了一下,也看了内存分布,总算明白了一些。

void main()
{
int *pp=new int[3];
//内存分布:
// (受保护的内存标志)   pp                                      (受保护的内存标志)
// ------|--------------|----------------------------------------|
// ------FD FD FD FD----CD CD CD CD---CD CD CD CD---CD CD CD CD---FD FD FD FD


*(pp+0)=0;
// (受保护的内存标志)   pp                                      (受保护的内存标志)
// ------|--------------|----------------------------------------|
// ------FD FD FD FD----00 00 00 00---CD CD CD CD---CD CD CD CD--FD FD FD FD


*(pp+1)=1;
// (受保护的内存标志)   pp                                      (受保护的内存标志)
// ------|--------------|-----------------------------------------|
// ------FD FD FD FD----00 00 00 00---01 00 00 00---CD CD CD CD---FD FD FD FD


*(pp+2)=2;
// (受保护的内存标志)   pp                                      (受保护的内存标志)
//-------|--------------|----------------------------------------|
//------FD FD FD FD----00 00 00 00---01 00 00 00---02 00 00 00---FD FD FD FD


*(pp+3)=3;
// (受保护的内存标志)   pp                                      
// ------|--------------|
// ------FD FD FD FD----00 00 00 00---01 00 00 00---02 00 00 00---03 00 00 00


cout<< "----- " << *(pp+0)<< *(pp+1)<< *(pp+2)<< *(pp+3) <<endl;
cout<< "----- " << *(pp+3)<<endl;

delete [] pp;//程序运行到这里时会出错 为什么呢?编译器是怎么做的?
// (受保护的内存标志)   pp                                      
// -----|---------------|                                        
// -----FD FD FD FD-----00 00 00 00----01 00 00 00----02 00 00 00----03 00 00 00

只找到了“受保护的内存标志”的起始位置,另外一个“受保护的内存标志”找不到了。
应该是因此而出错的吧

#18


晕 还是没整理好 再整理一下



void main()
{
int *pp=new int[3];
//内存分布:
// (受保护的内存标志)---pp----------------------------------------(受保护的内存标志)
// ------|--------------|-----------------------------------------|
// ------FD FD FD FD----CD CD CD CD---CD CD CD CD---CD CD CD CD---FD FD FD FD


*(pp+0)=0;
// (受保护的内存标志)---pp---------------------------------------(受保护的内存标志)
// ------|--------------|----------------------------------------|
// ------FD FD FD FD----00 00 00 00---CD CD CD CD---CD CD CD CD--FD FD FD FD


*(pp+1)=1;
// (受保护的内存标志)---pp---------------------------------------(受保护的内存标志)
// ------|--------------|-----------------------------------------|
// ------FD FD FD FD----00 00 00 00---01 00 00 00---CD CD CD CD---FD FD FD FD


*(pp+2)=2;
// (受保护的内存标志)---pp---------------------------------------(受保护的内存标志)
//-------|--------------|----------------------------------------|
//------FD FD FD FD----00 00 00 00---01 00 00 00---02 00 00 00---FD FD FD FD


*(pp+3)=3;
// (受保护的内存标志)   pp                                      
// ------|--------------|
// ------FD FD FD FD----00 00 00 00---01 00 00 00---02 00 00 00---03 00 00 00


cout<< "----- " << *(pp+0)<< *(pp+1)<< *(pp+2)<< *(pp+3) <<endl;
cout<< "----- " << *(pp+3)<<endl;

delete [] pp;//程序运行到这里时会出错 为什么呢?编译器是怎么做的?
// (受保护的内存标志)   pp                                      
// -----|---------------|                                        
// -----FD FD FD FD-----00 00 00 00----01 00 00 00----02 00 00 00----03 00 00 00

只找到了“受保护的内存标志”的起始位置,另外一个“受保护的内存标志”找不到了。
应该是因此而出错的吧

#19


数组最后一位是受保护的..

#20


mark

#21


remark

#22


数组最后一位是受保护的..
====================
不是这样
vc的debug版本会做检测
release版本看到这种错误提示

#23


对 楼上正解
debug检测

#24


mark

#25


失败是成功之母啊!

#26


debug 在new出的内存最后有检测。

#27


感觉yaoyansi() 正解。。

#28


学到了,赚了,mark

#29


hehe,学业有成啊!回家教书喽!嘿嘿

#30


ok

#31


才new了3个,现在要delete 4个
这么简单的东西这么讲得如此复杂?

#32


才new了3个,现在要delete 4个
这么简单的东西这么讲得如此复杂?

-----------------------
汗,你从哪里得出结论要delete 4个

#33


好像 不是那样 如果把*(pp+4)的内容在填充成fd的话仍然有错误,期待正解

#34


当运行*(pp+3)=3时,指针pp已经指向了新的内存空间,这时delete[]pp,又没有new出新的出来,delete就出错了
小菜鸟,呵呵

#35


回复人:playboy1983() ( 一级(初级)) 信誉:100  2006-11-17 18:01:20  得分:0


好像 不是那样 如果把*(pp+4)的内容在填充成fd的话仍然有错误,期待正解
------------------------------------------------------------------------------------
强人!

偶试了一下,给*(pp+4)填充0Xfdfdfdfd后,在delete时还是会出错。

{
int *pp=new int[3];

 *(pp+0)=0;
 *(pp+1)=1;
 *(pp+2)=2;

 *(pp+3)=3;

 *(pp+4)=0xfdfdfdfd;
}

不知道为什么,不知道编译器做了什么手脚!

#36


mark,mark

#37


怎么没高手回帖了?顶一下

#1


偶用的是vc6

#2


偶感觉可能程序要释放*(pp+3)处的内存,所以导致错误吧。
再深层的原因不知了。

顶一下

#3


明明知道是错了还要这么用

#4


内存中可以看到初始化为 CD CD CD CD CD CD CD CD CD CD CD CD FD FD FD FD (在第一个CD前也有 FD FD FD FD)
 0xFD( deFencde Data ) 初始化受保护的内存(debug 版在动态分配内存的前后加入保护内存以防止越界访问)
而你的 *(pp+3)=3; 正好把 FD FD FD FD 这改为了03 00 00 00 ,应该是删除这的时候导致出错

#5


delete [] pp;//程序运行到这里时会出错 为什么呢?编译器是怎么做的?
delete与[]之间没有空格吧?

#6


应该是没有空格的缘故

#7


weixing979(★★★闪电侠★★★) 正解
我在VC里F5调试你的程序,DEBUG记录里有这么一段:
memory check error at 0x00371EDC = 0x03, should be 0xFD.
memory check error at 0x00371EDD = 0x00, should be 0xFD.
memory check error at 0x00371EDE = 0x00, should be 0xFD.
memory check error at 0x00371EDF = 0x00, should be 0xFD.

#8


我发现把这句:
 *(pp+3)=3;
注释掉就没不会有错误了

莫非delete删除的空间范围是编译器根据你访问的范围来决定释放范围的?

#9


饿,果然如weixing979(★★★闪电侠★★★)所说,跟踪的话会发现错误是发生在*(pp+3)=3;
而不是delete那里

#10


才new了3个,现在要delete 4个
不出错才怪呢

#11


觉得weixing979(★★★闪电侠★★★) 的有理!

#12


mark

#13


mark

#14



诸位是如何在vc下查看内存分布的啊?

#15


先在某行打上断点,然后F5,调试时 View -- Debug Windows -- Memory

#16


多谢诸位的指点,刚才也和同学讨论了一下,也看了内存分布,总算明白了一些。

void main()
{
int *pp=new int[3];
//内存分布:
// (受保护的内存标志)   pp                                      (受保护的内存标志)
//      |               |                                        |
//      FD FD FD FD    CD CD CD CD   CD CD CD CD   CD CD CD CD   FD FD FD FD


*(pp+0)=0;
// (受保护的内存标志)   pp                                      (受保护的内存标志)
//      |               |                                        |
//      FD FD FD FD    00 00 00 00   CD CD CD CD   CD CD CD CD   FD FD FD FD


*(pp+1)=1;
// (受保护的内存标志)   pp                                      (受保护的内存标志)
//      |               |                                        |
//      FD FD FD FD    00 00 00 00   01 00 00 00   CD CD CD CD   FD FD FD FD


*(pp+2)=2;
// (受保护的内存标志)   pp                                      (受保护的内存标志)
//      |               |                                        |
//      FD FD FD FD    00 00 00 00   01 00 00 00   02 00 00 00   FD FD FD FD


*(pp+3)=3;
// (受保护的内存标志)   pp                                      
//      |               |                                        
//      FD FD FD FD    00 00 00 00   01 00 00 00   02 00 00 00   03 00 00 00


cout<< "----- " << *(pp+0)<< *(pp+1)<< *(pp+2)<< *(pp+3) <<endl;
cout<< "----- " << *(pp+3)<<endl;

delete [] pp;//程序运行到这里时会出错 为什么呢?编译器是怎么做的?
// (受保护的内存标志)   pp                                      
//      |               |                                        
//      FD FD FD FD    00 00 00 00   01 00 00 00   02 00 00 00   03 00 00 00

只找到了“受保护的内存标志”的起始位置,另外一个“受保护的内存标志”找不到了。
应该是因此而出错的吧

#17


晕 格式全乱了! 再整理一下
多谢诸位的指点,刚才也和同学讨论了一下,也看了内存分布,总算明白了一些。

void main()
{
int *pp=new int[3];
//内存分布:
// (受保护的内存标志)   pp                                      (受保护的内存标志)
// ------|--------------|----------------------------------------|
// ------FD FD FD FD----CD CD CD CD---CD CD CD CD---CD CD CD CD---FD FD FD FD


*(pp+0)=0;
// (受保护的内存标志)   pp                                      (受保护的内存标志)
// ------|--------------|----------------------------------------|
// ------FD FD FD FD----00 00 00 00---CD CD CD CD---CD CD CD CD--FD FD FD FD


*(pp+1)=1;
// (受保护的内存标志)   pp                                      (受保护的内存标志)
// ------|--------------|-----------------------------------------|
// ------FD FD FD FD----00 00 00 00---01 00 00 00---CD CD CD CD---FD FD FD FD


*(pp+2)=2;
// (受保护的内存标志)   pp                                      (受保护的内存标志)
//-------|--------------|----------------------------------------|
//------FD FD FD FD----00 00 00 00---01 00 00 00---02 00 00 00---FD FD FD FD


*(pp+3)=3;
// (受保护的内存标志)   pp                                      
// ------|--------------|
// ------FD FD FD FD----00 00 00 00---01 00 00 00---02 00 00 00---03 00 00 00


cout<< "----- " << *(pp+0)<< *(pp+1)<< *(pp+2)<< *(pp+3) <<endl;
cout<< "----- " << *(pp+3)<<endl;

delete [] pp;//程序运行到这里时会出错 为什么呢?编译器是怎么做的?
// (受保护的内存标志)   pp                                      
// -----|---------------|                                        
// -----FD FD FD FD-----00 00 00 00----01 00 00 00----02 00 00 00----03 00 00 00

只找到了“受保护的内存标志”的起始位置,另外一个“受保护的内存标志”找不到了。
应该是因此而出错的吧

#18


晕 还是没整理好 再整理一下



void main()
{
int *pp=new int[3];
//内存分布:
// (受保护的内存标志)---pp----------------------------------------(受保护的内存标志)
// ------|--------------|-----------------------------------------|
// ------FD FD FD FD----CD CD CD CD---CD CD CD CD---CD CD CD CD---FD FD FD FD


*(pp+0)=0;
// (受保护的内存标志)---pp---------------------------------------(受保护的内存标志)
// ------|--------------|----------------------------------------|
// ------FD FD FD FD----00 00 00 00---CD CD CD CD---CD CD CD CD--FD FD FD FD


*(pp+1)=1;
// (受保护的内存标志)---pp---------------------------------------(受保护的内存标志)
// ------|--------------|-----------------------------------------|
// ------FD FD FD FD----00 00 00 00---01 00 00 00---CD CD CD CD---FD FD FD FD


*(pp+2)=2;
// (受保护的内存标志)---pp---------------------------------------(受保护的内存标志)
//-------|--------------|----------------------------------------|
//------FD FD FD FD----00 00 00 00---01 00 00 00---02 00 00 00---FD FD FD FD


*(pp+3)=3;
// (受保护的内存标志)   pp                                      
// ------|--------------|
// ------FD FD FD FD----00 00 00 00---01 00 00 00---02 00 00 00---03 00 00 00


cout<< "----- " << *(pp+0)<< *(pp+1)<< *(pp+2)<< *(pp+3) <<endl;
cout<< "----- " << *(pp+3)<<endl;

delete [] pp;//程序运行到这里时会出错 为什么呢?编译器是怎么做的?
// (受保护的内存标志)   pp                                      
// -----|---------------|                                        
// -----FD FD FD FD-----00 00 00 00----01 00 00 00----02 00 00 00----03 00 00 00

只找到了“受保护的内存标志”的起始位置,另外一个“受保护的内存标志”找不到了。
应该是因此而出错的吧

#19


数组最后一位是受保护的..

#20


mark

#21


remark

#22


数组最后一位是受保护的..
====================
不是这样
vc的debug版本会做检测
release版本看到这种错误提示

#23


对 楼上正解
debug检测

#24


mark

#25


失败是成功之母啊!

#26


debug 在new出的内存最后有检测。

#27


感觉yaoyansi() 正解。。

#28


学到了,赚了,mark

#29


hehe,学业有成啊!回家教书喽!嘿嘿

#30


ok

#31


才new了3个,现在要delete 4个
这么简单的东西这么讲得如此复杂?

#32


才new了3个,现在要delete 4个
这么简单的东西这么讲得如此复杂?

-----------------------
汗,你从哪里得出结论要delete 4个

#33


好像 不是那样 如果把*(pp+4)的内容在填充成fd的话仍然有错误,期待正解

#34


当运行*(pp+3)=3时,指针pp已经指向了新的内存空间,这时delete[]pp,又没有new出新的出来,delete就出错了
小菜鸟,呵呵

#35


回复人:playboy1983() ( 一级(初级)) 信誉:100  2006-11-17 18:01:20  得分:0


好像 不是那样 如果把*(pp+4)的内容在填充成fd的话仍然有错误,期待正解
------------------------------------------------------------------------------------
强人!

偶试了一下,给*(pp+4)填充0Xfdfdfdfd后,在delete时还是会出错。

{
int *pp=new int[3];

 *(pp+0)=0;
 *(pp+1)=1;
 *(pp+2)=2;

 *(pp+3)=3;

 *(pp+4)=0xfdfdfdfd;
}

不知道为什么,不知道编译器做了什么手脚!

#36


mark,mark

#37


怎么没高手回帖了?顶一下