【问题标题】:Using memcpy with array name [duplicate]使用带有数组名称的 memcpy [重复]
【发布时间】:2012-03-29 17:31:01
【问题描述】:

可能重复:
C: How come an array's address is equal to its value?

我最近在我的项目中发现代码调用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 中验证了这种行为。

【问题讨论】:

    标签: c++


    【解决方案1】:

    是的,数组的地址与其第一个元素的地址相同。
    因此无需更改memcpy 调用。除非你担心数组的定义以后可能会变成一个指针(比如int* a = new int[10];)。

    当然,如果您无论如何都要对程序进行更改,最好放弃整个 memcpy 并改用真正的 C++。

    【讨论】:

      【解决方案2】:

      &a是数组的地址; a 可以隐式转换为第一个元素的地址。两者都具有相同的地址,因此在转换为 void* 时都会给出相同的值。

      有什么陷阱吗?

      memcpy 不是类型安全的,因此很容易编写可编译但表现不佳的代码;例如,如果a 是一个指针而不是一个数组,那么sizeof a 将编译但给出错误的值。 C++ 的类型安全模板可以防止这种情况:

      std::copy(b, std::end(b), a); // will only compile if `b` has a known end.
      

      【讨论】:

        【解决方案3】:

        就像你说的,没关系。

        当作为参数传递时,数组的名称将“衰减”为指向其第一个元素的指针。

        【讨论】:

          【解决方案4】:

          数组的名称等于数组开头的地址,因此两者含义相同。请参阅How come an array's address is equal to its value in C?(这是一个 C 问题,但对于 C++ 也是如此)。

          【讨论】:

          • 是的,你链接的帖子给出了很好的答案。
          猜你喜欢
          • 2016-04-06
          • 2014-07-09
          • 1970-01-01
          • 1970-01-01
          • 2017-06-10
          • 1970-01-01
          • 2015-06-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多