【问题标题】:Memcpy into an array inside a malloced structureMemcpy 到 malloced 结构内的数组中
【发布时间】:2014-02-12 05:22:20
【问题描述】:

这是我的场景。

struct X {
char A[10];
int foo;
};
struct X *x;
char B[10]; // some content in it.
x = malloc(sizeof(struct X));

B的内容复制到A,为什么下面的语法是正确的:

memcpy(x->A, B, sizeof(x->A));

这里x->A被视为一个指针,所以我们不需要&。但是我们应该需要sizeof(*x->A) 对吗?但是使用* 无法正常工作,而没有* 则可以正常工作。

是不是sizeof 运算符不把A 当作指针对待?

【问题讨论】:

    标签: c arrays pointers sizeof memcpy


    【解决方案1】:

    A 不是指针,它是一个数组。所以sizeof(x->A) 是正确的语法,它是整个数组的大小,即10

    确实,在许多情况下,数组名称会转换为指向第一个元素的指针。但sizeof(arrayname) 不是其中之一。

    【讨论】:

    • 这种 sizeof 的行为在不同的 C 实现和平台上是一致的。我现在知道它在 x86 linux 机器上与 gcc 一起工作。其他人呢?
    • @vivekzhere 是由 C 标准保证的,所以所有的实现都应该遵循这个规则。
    • @vivekzhere 但是当数组名称作为函数参数传递时要小心,在这种情况下它会衰减为指针。
    【解决方案2】:

    sizeof(*x->A) 给出一个字符的大小(1 字节),而 size0f(x->A) 给出整个数组的大小(10 字节)。

    【讨论】:

      【解决方案3】:

      sizeof(*x->A) 等价于sizeof(x->A[0])

      sizeof(*x->A) 在这里再见。所以 memcpy 只会发生在一个字节上。

      这是sizeof(x->A) 是正确的程序。

      【讨论】:

      • x->A[0] 的大小是一个char 的大小,即(根据定义)1
      【解决方案4】:

      尽管在许多情况下,数组名称会衰减为指针(例如您的示例中 memcpy() 的第一个参数),但有一些不会,sizeof 运算符参数就是其中之一。其他例子是一元& 运算符参数等。C++ 有更多的场景(例如数组引用的初始化器)。

      【讨论】:

        【解决方案5】:

        只是为了添加到以前的 cmets

        sizeof(x->A) 是正确的 sizeof(*x->A) 是不正确的,因为 -> 的优先级高于 * 所以首先获得 A 的地址(X->A)然后 * 再次尊重第一个字节(一个字符字节)。

        不要忘记 sizeof 运算符不考虑 '\0' 字符。如果字符串 "Hello" 被 A 指向,则返回 5(数组大小为 6,包括 '\0'), 因此,在复制到B 时,您必须明确添加'\0',或者您可以将要复制的字节数增加一,如下所示。

        memcpy(x->A, B, sizeof(x->A) + 1);
        

        【讨论】:

          猜你喜欢
          • 2016-02-12
          • 2015-12-29
          • 2023-04-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-10
          相关资源
          最近更新 更多