如何复制到结构内部的数组?

how to copy to array inside struct?

如何复制到 flexible array inside struct in c?

    #include <stdio.h>
    #include <string.h>
    
    typedef struct
    {
        int val;
        char buf[];
    } foo;
    
    int main()
    {
        foo f;
        f.val = 4;
        // f.buf = "asd"; -> invalid use of flexible array member
        memcpy(f.buf, "asd[=10=]", 4);
        printf("%s\n", f.buf);
    }

输出:

    asd
    *** stack smashing detected ***: terminated
    Aborted (core dumped)

此外,如果结构声明为:

    typedef struct
    {
        char buf[];
    } foo

vscode 编辑器报错:

    incomplete type is not allow

gcc 给出错误:

    error: flexible array member in a struct with no named members
        6 |     char buf[];

为什么现在允许结构中的数组但允许指针? (char *buf).

此外,如果一个结构体有一个灵活的数组,它的sizeof(struct containsFlexArray)是什么?当它没有维度时,如何动态解析它的数组?

编辑: 如果以上在 C++ 中有效,因为不完整的数组“衰减”到已知长度的指针(x64 中为 8 个字节),为什么 c 中也不是这种情况?如果我查看 asm,我发现程序没有为结构分配足够的堆栈(它只为 foo.val member, but not bur foo.buf member 分配 space,在这种情况下,程序会尝试使用覆盖 foo.val 成员(通过使用它的地址而不是foo.buf),这导致stack smashing detected。但是为什么它以这种错误的方式实现?(所以我也想知道引入灵活数组的基本原理)

您可能想阅读有关 flexible array member here 的信息。

看起来,当在 struct 中使用 flexible array 时,必须至少有一个其他数据成员,并且灵活的数组成员必须在最后。

您可能还需要对 flexible array members in C here

的用法进行澄清

让我们在这里使用 intel/amd 架构,其中 char => 1 字节 int => 4 并且 long 是 8 字节长。

结构对齐是这里的一个问题。您会看到,当您在 c 中声明一个结构时,编译器将其视为单独的块。所以如果你有这样的结构:

struct a {
   long l;
   char c1;
   char c2;
}

编译器查看第一个使用的类型,并为 l 分配 8 个字节的内存,查看 c 并确定 c1 比 l 短,而不是弄清楚 c1 的类型是什么,它为 l 分配 8 个字节的数据c1.它对 c2 做同样的事情。所以你最终得到的结构是 24 字节长,只使用了 10 个字节。如果你在哪里使用这个:

struct b {
  char c1;
  long l;
  char c2;
}

这将为c1分配1个字节,为l分配8个字节,为c2分配8个字节。所以你最终得到 17 个字节和 10 个使用。好像你有这个:

struct b {
  char c1;
  char c2;
  long l;
}

好吧,它为 c1 分配了 1 个字节,为 c2 分配了 1 个字节,为 l 分配了 8 个字节。总共 10 个字节,但全部使用了 10 个。

那跟数组有什么关系呢?你看看你有没有:

struct aa {
   char a;
   long b[];
}

这样一开始就知道至少要为b分配一个字节。当你没有 char a,

struct aa {
   long b[];
}

编译器可能不会分配任何内存(分配 0 字节),因为它根本不知道要分配多少内存。

编辑: 离开我的电脑,同时弹出其他答案。另一个回答很好!!!但我希望这可以帮助您了解正在发生的事情。

当您在main() 中声明一个实例时,您没有初始化buf[] 数组。编译器不知道要分配多少内存。堆栈粉碎是一种编译器功能,可防止您的程序对您的计算机做...坏事。将数字添加到 typedef 结构中的数组声明。 像这样: ` #include #include

typedef struct
{
    int val;
    char buf[5];
} foo;

int main()
{
    foo f;
    f.val = 4;
    // f.buf = "asd"; -> invalid use of flexible array member
    memcpy(f.buf, "asd[=10=]", 4);
    printf("%s\n", f.buf);
}`