前几天遇到一个神奇的bug,某些特殊情况下释放动态数组时竟然卡死,有些环境还报内存操作非法错误。最后发现原来是自己基础知识还是不牢固,一些暗坑没有留意。报错代码的大致如下。
#define INT16U unsigned short
void Test(int size)
{
INT16U * testArr = new INT16U[size];
memset(testArr, 0, sizeof(testArr));
// code...
delete[] testArr; //这里卡死或报错
printf("Finish");
}
当传递size参数为1时就卡死或报错。
其原因是memset函数用法错了。当数组是静态数组时,sizeof(testArr)得到的结果就是数组所占内存的大小。但是当数组是动态数组时就不能这样初始化,因为动态数组testArr是一个指针,它的size永远是4,sizeof(testArr)的结果也是4。而当我们要申请一个长度为1的INT16U数组时,它的实际内存只有2个字节,memset却操作了4个字节。这就导致了内存操作错误。同样的问题还会存在于动态char数组、unsigned char数组。
动态数组初始化的正确做法应该是:memset(testArr,0,sizeof(类型)*长度)
结合上文的例子,修改为如下代码后问题解决。
#define INT16U unsigned short
void Test(int size)
{
INT16U * testArr = new INT16U[size];
memset(testArr, 0, sizeof(INT16U) * size); // 动态数组初始化
// code...
delete[] testArr;
printf("Finish");
}
有些知识点脑子里是记得清清楚楚,但是到了实际应用的时候缺总是没注意到,说明基础知识还是不牢固,惭愧惭愧。