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

时间:2022-01-12 02:28:24

 

楼主yaoyansi()2006-11-16 20:58:00 在 C/C++ / C++ 语言 提问

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;//程序运行到这里时会出错   为什么呢?编译器是怎么做的?  
   
  }  
  问题点数:10、回复次数:37Top

 

1 楼yaoyansi()回复于 2006-11-16 21:00:55 得分 0

偶用的是vc6Top

4 楼weixing979(★★★闪电侠★★★)回复于 2006-11-16 21:19:56 得分 3

内存中可以看到初始化为   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   ,应该是删除这的时候导致出错Top

7 楼alainpro(Alain)回复于 2006-11-16 22:41:33 得分 3

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.  
  Top

9 楼gkisme(Fighting Dreamer)回复于 2006-11-16 22:46:05 得分 0

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

 

yaoyansi()回复于 2006-11-17 11:22:07 得分 0

 

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

15 楼weixing979(★★★闪电侠★★★)回复于 2006-11-17 12:00:28 得分 2

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

16 楼yaoyansi()回复于 2006-11-17 12:30:17 得分 0

多谢诸位的指点,刚才也和同学讨论了一下,也看了内存分布,总算明白了一些。      
    
  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  
   
  只找到了“受保护的内存标志”的起始位置,另外一个“受保护的内存标志”找不到了。  
  应该是因此而出错的吧  
  Top

19 楼dongbicheng1983()回复于 2006-11-17 12:42:52 得分 0

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

22 楼39457760(人间一日,网上一年◎分要多多的给,贴要慢慢的结)回复于 2006-11-17 13:42:30 得分 0

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

23 楼AVRobust(心镜止水)回复于 2006-11-17 13:55:38 得分 0

对   楼上正解  
  debug检测  
  Top

26 楼akirya(坏[其实偶不是什么所谓的坏人])回复于 2006-11-17 15:02:24 得分 0

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

33 楼playboy1983()回复于 2006-11-17 18:01:19 得分 2

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

35 楼yaoyansi()回复于 2006-11-20 09:47:31 得分 0

回复人: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;  
  }  
   
  不知道为什么,不知道编译器做了什么手脚!