2008年7月31日星期四

GCC和VS对动态分配数组的不同结果

今天在这个上花了很多时间,不过看来结果还是很值得欣慰的。直接看代码吧~

#include <conio.h>
#include <iostream>
#include <stdio.h>
#include <string.h>    
#include "SolveHead.h"
using namespace std;

int main()
{
  int *ptr = new int[5];  // 在这里分配了内存
  int *p = ptr;  // 这个是下面的失败后我故意放的一个

  ptr[1] = 123;  // 写入值,下面操作
  cout<<*(++ptr)<<endl;  // 这里,VS会中断警告
  cout<<*(++p)<<endl;  // 如果把上面的删除,这行可以正常的运行,并显示123

  delete[]  ptr;  // VS中断后的断点指示处。很奇怪,为什么在这里

  cout<<endl<<"Press any key to exit!"<<endl;
  getch();
  return 0;
}


VS会产生如下警告中断 但是,经过骨头的测试,GCC可以正常编译通过和运行~ 然后我按照上面的提示,跟踪了下dgbdel.cpp,发现那个指针有问题。于是发现解决方法

// 只要即可
delete[]  (--ptr);

// 我在前面把ptr自增了1,导致指针移位,结果在delete的时候不是指向第一个。即
ptr == &ptr[1];


所以VC报错了。但是这里还有一个问题,GCC为什么能正常的编译通过,并且正常的运行? 于是偶想到了检测内存,因为GCC是按照标准的CPP来的,所以如果他的delete删的不是首地址,而是中间的某个地址,那么前面的那些就会造成memory leaks。 于是,为了验证,骨头用下面的代码进行了测试

#include <iostream>

int main(){
    while (true) {
        int *ptr = new int[5];
        ptr++;
        delete [] ptr;
    }
}

得到的结果很有意思,大家看图吧 这个是用正常代码的测试结果

这个是用了测试代码的结果

结果很明显,用了测试代码的程序占了100多MB的内存,也就是说,前面地址的所对应的内存的确泄露了~

不知道这个是GCC的设计问题还是什么~不过用GCC作为编译器的各位还是要小心了~

看来VC在这方便的检测做的还是比较好的—。—

1 条评论:

1、可以使用<b>、<i>、<a>等Html标志,让评论更有特色...
2、支持OpenID登录,技术达到国际先进水平。但切记,评论内容不代表本站观点!
3、当遇到“连接被重置”、“连接超时”和“此网页无法访问”等而发表不了评论的话,请多刷新几次页面,或迟三分钟后再试;
4、对你的浏览造成不便,站长在此代表全国G.FW工作人员向你鞠躬致歉!!!