本节书摘来自异步社区出版社《从缺陷中学习C/C++》一书中的第6章,第6.3节,作者: 刘新浙 , 刘玲 , 王超 , 李敬娜 , ,更多章节内容可以访问云栖社区“异步社区”公众号查看。
6.3 数组传参时的sizeof
从缺陷中学习C/C++
代码示例
void copy(int a[], int b[]) {
memcpy(b, a, sizeof(a));
}
现象&结果
copy函数执行后,内存中的内容与设想不符,目标数组b中的内容不完整,没有把源数组a中的内容全部复制过来。
Bug分析
memcpy函数的原型是void memcpy(void dest, const void *src, size_t n);,它的功能是从源src所指的内存地址的起始位置开始复制n个字节到目标dest所指的内存地址的起始位置中。上述程序中,copy函数的两个形参是数组a和数组b,函数体中调用了memcpy函数,并且为memcpy函数的第三个参数赋值sizeof(a)。程序的本意是期望sizeof(a)返回数组a所占的字节数,通过memcpy函数,把源数组a中的内容全部复制到目标数组b中。但是数组int a[]作为copy函数的形参,在copy函数体内将退化成指针,所以,sizeof(a)返回的是指针的字节数,而不是数组a的字节数。因此,数组b中只是部分复制了数组a中的内容。解决办法是:在copy函数中增加一个参数,作为数组复制的字节数。
正确代码
void copy(int a[], int b[], int len) {
memcpy(a, b, sizeof(int)*len);
}
void del(int a[], int len) {
memset(a, 0, sizeof(int)*len);
}
或者用数组的引用方式传参:
void copy(int a[], int (&b)[]) {
memcpy(a, b, sizeof(b));
}
编程建议
数组传递参数时,连同数组长度一起传入是一个好方法。或者用std::vector代替数组可以避免不必要的麻烦。使用数组的引用,作为函数的参数,也可以解决上面的问题。
本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。