我最近在项目中找到了使用数组名称
的地址调用memcpy
的代码
int a[10];
memcpy(&a, &b ,sizeof(a));
令人惊讶的是(对我而言)似乎有效。
我应该将其更改为memcpy(a,b,sizeof(a));
吗?
C ++规范是否允许? 有人能指出我有关这种行为的资源吗?有没有陷阱?
我也检查了
assert((void*)&a == (void*)a);
和&a
确实与a
相同(除了它的类型)。
我在VS2005,VS2008和VS2010中验证了这种行为。
答案 0 :(得分:4)
&a
是数组的地址; a
可以隐式转换为第一个元素的地址。两者都具有相同的地址,因此转换为void*
时两者都会给出相同的值。
有任何陷阱吗?
memcpy
不是类型安全的,因此编写编译但行为错误的代码非常容易;例如,如果a
是指针而不是数组,那么sizeof a
将编译但是给出错误的值。 C ++的类型安全模板可以防止这种情况:
std::copy(b, std::end(b), a); // will only compile if `b` has a known end.
答案 1 :(得分:2)
数组的名称求值为数组开头的地址,因此两者具有相同的含义。请参阅How come an array's address is equal to its value in C?(这是一个C问题,但C ++也是如此)。
答案 2 :(得分:1)
就像你说的那样,没关系。
当作为参数传递时,数组的名称将“衰减”为指向其第一个元素的指针。
答案 3 :(得分:1)
是的,数组的地址与第一个元素的地址相同
因此无需更改memcpy
电话。除非您担心数组的定义可能会在以后更改为指针(例如int* a = new int[10];
)。
当然,如果您要对程序进行更改,最好省略整个memcpy
并使用真正的C ++。