今天遇到一个奇怪的问题,同样的程序,在Windows下调试已经没问题,可到Linux下编译运行结果就是不一致,用gdb单步跟踪,
最终发现一个变量的值很奇怪,没有给它赋值,但它确有一个很正常的值。于是我做了一个小实验:
#include <iostream>
using namespace std;
void f(const int& b){}
int main()
{
int *a;
int b;
int c;
f(b);
f(c);
cout << (void*)a<< endl;
a = new int[2];
cout << (void*)*a << endl;
delete a;
cout << (void*)a << endl;
cout << (void*)b << "," << (void*)c << endl;
return 0;
}
这样一段小程序在Windows下使用使用VC6和VC7.1编译执行,运行结果不完全一致,在Linux(FC7)下用g++ 4.1.2编译器编译
,运行结果更是出乎意料。Windows下栈变量定义后会被初始化成全C,而Linux是保持原内存的值不变,Windows新申请的内存会
被初始化成全CD,Linux看到的结果是0(是否一定初始化成0,不确定),内存释后Linux变成0,Windows下不太一致,以往的经
验会变成feee或全d,这次看到的不是。
结果确定,问题是由于局部变量没有显式初始化,如果在简单的程序里,使用未初始化的变量编译器会报warning,但像上面
的程序,变量的引用或指针被传到其他函数,然后再使用,编译器就不报了,所以靠编译器提醒还是不够的。高版本的VC会有运
行时检查,如果使用的未初始化的变量会在运行时报告,但也不是每次都报,所以只能靠自己写程序的时候注意了。
顺便再写一个昨天遇到的小问题:构造函数抛异常会造成内存泄露吗?
class A{
public:
int a;
A()
{
throw(1);
}
~A()
{
}
};
void main()
{
A* p = 0;
try
{
p = new A;
}
catch(int)
{
}
p = new A;
}
显然这个程序里p是拿不到地址的,也就是说没有办法delete,但会不会有内存泄露呢?理论上抛出异常时,内存已经申请成功,应该释放。实验证明,try里面的new系统没有报内存泄露,但try外面的new却报了,网上的资料显示,编译器会对构造函数抛异常的情况作善后处理,释放掉申请的内存,但为什么没有try的new报了内存泄露,网上没提到。当然,有异常一定要try的。