关于一个整型参数内存溢出的思考
对于使用c/c++编程的人来说,遇到char*类型的缓冲区溢出再平常不过了,不过我最近却遇到一个整型参数的缓冲区溢出问题:
一个系统中有两个模块A和B,模块B会通过以下接口调用模块A获取一些参数:
getProperty(int prop,unsigned int* value)
模块A在给value赋值时使用了如下语句:
*(long long *)value = <一个32位整数>;
而模块B中函数Func中按如下方法使用了此接口:
unsigned int myValue = 0;
getProperty(PROP_NAME,&myValue);
在wince平台上使用debug版本测试程序时可能会出现以下现象:
1. 调用模块A的接口后函数Func中的某些局部变量突然被清零。
2. 退出函数Func时报“内存溢出”问题,但程序仍然可以运行下去。
使用Release版本时不再报“内存溢出”错误。
造成上面问题的原因:由于模块A会通过参数指针改写模块B中声明的局部变量的值,而参数有效区域本来只有sizeof(unsign int)即4字节,但赋值时却强制把它当作long long类型的变量,它占sizeof(long long)即8字节,因此就会将参数有效区域后面的4个字节错误改写,而此区域应该就是存放模块B中函数Func的局部变量的地方,因此有时局部变量的值突然被修改,变为零是因为32位整数当64位看待时后面都为0。
至于在Debug版本时报内存溢出错误估计是因为此时有对栈进行内存检查的代码,而Rlease版本为了提高速度则去掉了。
上面这个问题查了很久,原因在于模块A与模块B分别属于两个不同的部门,模块B根本不知模块A中使用了long long类型的数据,因为按照接口约定是unsigned int。
因此对于模块之间接口的调用,一定要注意参数空间是否足以容纳要返回的内容,同时接口双方务必不要随意改变对参数类型的假定。