简体   繁体   English

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

[英]how to copy to array inside struct?

How to copy to flexible array inside struct in c?如何复制到 c 中结构内的flexible array

    #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\0", 4);
        printf("%s\n", f.buf);
    }

output: output:

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

Also, if the struct was declared as:此外,如果结构被声明为:

    typedef struct
    {
        char buf[];
    } foo

vscode editor gives error: vscode 编辑器报错:

    incomplete type is not allow

and gcc gives error:和 gcc 给出错误:

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

Why is array in struct now allowed but pointer is?为什么现在允许结构中的数组但指针是? ( char *buf ). ( char *buf )。

Also, If a struct has a flexible array, what is its sizeof(struct containsFlexArray) ?另外,如果一个结构有一个灵活的数组,它的sizeof(struct containsFlexArray)是多少? How can I dynamically resolve its array, when it has no dimension?当它没有维度时,如何动态解析它的数组?

EDIT: if the above works in C++, because the incomplete array "decay" to pointer of known length (8 bytes in x64), why is this not also the case in c ?编辑:如果上述方法在 C++ 中有效,因为不完整的数组“衰减”到已知长度的指针(x64 中为 8 个字节),为什么在c中也不是这种情况? If I peek to asm, I see the program does not allocate enough stack for the struct (it allocates only space for foo.val member, but not bur foo.buf member , in which case the program tries to use override the foo.val member (by using its address instead of foo.buf ), which causes the stack smashing detected . But why is it implemented this wrong way? (So I want to know the rationale behind introducing flexible array as well)如果我查看 asm,我看到程序没有为结构分配足够的堆栈(它只为foo.val member, but not bur foo.buf member分配空间,在这种情况下,程序尝试使用覆盖foo.val成员(通过使用其地址而不是foo.buf ),这会导致stack smashing detected 。但是为什么它以这种错误的方式实现?(所以我也想知道引入灵活数组的原理)

You may want to read information on flexible array member here .您可能想在此处阅读有关flexible array member的信息。

It seems as, when using a flexible array in a struct there must be at least one other data member and the flexible array member must be last.似乎,在struct中使用flexible array时,必须至少有一个其他数据成员,并且灵活数组成员必须在最后。

And also you may have an element of clarification concerning the usage of flexible array members in C here您还可以在此处flexible array members in C的使用进行澄清

You did not initialize the buf[] array when you declared an instance in main().当您在 main() 中声明一个实例时,您没有初始化 buf[] 数组。 The compiler does not know how much memory to allocate.编译器不知道要分配多少 memory。 The stack smashing is a compiler feature that keeps your program from doing... bad things to you computer.堆栈粉碎是一种编译器功能,可防止您的程序对您的计算机造成……坏事。 Add a number to your array declaration in typedef struct.向 typedef 结构中的数组声明添加一个数字。 Like this: ` #include <stdio.h> #include <string.h>像这样:` #include <stdio.h> #include <string.h>

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\0", 4);
    printf("%s\n", f.buf);
}`

lets use intel/amd architecture here where char => 1 byte int => 4 and long is 8 bytes long.让我们在这里使用 intel/amd 架构,其中 char => 1 byte int => 4 并且 long 是 8 字节长。

Struct alignment is an issue here.结构 alignment 是这里的一个问题。 You see when you declare a struct in c , compiler looks at it as individual block.您会看到,当您在c中声明一个结构时,编译器会将其视为单独的块。 So if you have a struct like this:因此,如果您有这样的结构:

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

compiler looks at the first type used, and allocates 8 bytes of memory for l, looks at c and determines that c1 is shorter than l and rather than figure out what c1's type is, it allocates 8 bytes of data for c1.编译器查看第一个使用的类型,并为 l 分配 8 个字节的 memory,查看 c 并确定 c1 比 l 短,而不是弄清楚 c1 的类型是什么,而是为 c1 分配 8 个字节的数据。 It does the same for c2.对 c2 也是如此。 So you end up with struct that is 24 bytes long and only 10 are used.所以你最终得到了 24 个字节长的结构,并且只使用了 10 个。 Where if you use this:如果你使用这个:

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

this will allocate 1 byte for c1, 8 byte for l, and 8 bytes for c2.这将为 c1 分配 1 个字节,为 l 分配 8 个字节,为 c2 分配 8 个字节。 So you end up with 17 bytes and 10 used.所以你最终使用了 17 个字节和 10 个字节。 Where as if you have this:好像你有这个:

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

well it allocates 1 byte for c1, 1 byte for c2, and 8 bytes for l.它为 c1 分配 1 个字节,为 c2 分配 1 个字节,为 l 分配 8 个字节。 In total 10 bytes but all 10 are used.总共 10 个字节,但所有 10 个都被使用。

So what does it have to do with array?那么它和数组有什么关系呢? You see if you have:你看看你有没有:

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

This will know to allocate at least one byte for b initially.这将知道最初为b分配至少一个字节。 Where when you do not have char a ,当你没有 char a时,

struct aa {
   long b[];
}

Compiler might not allocate any memory (allocate 0 bytes), because it simply does not know how much to allocate.编译器可能不会分配任何 memory(分配 0 字节),因为它根本不知道要分配多少。

EDIT: Left my PC and in mean time other answer popped up.编辑:离开我的电脑,同时弹出其他答案。 The other answer is very good.!!另一个答案很好。! But I hope this helps you understand what is going on.但我希望这可以帮助您了解正在发生的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM