【发布时间】:2021-05-04 07:56:18
【问题描述】:
如何在c中的struct内部复制到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);
}
输出:
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 分配空间,在这种情况下,程序尝试使用覆盖 foo.val 成员(通过使用其地址而不是 @ 987654332@),导致stack smashing detected。但是为什么它以这种错误的方式实现?(所以我也想知道引入灵活数组的原理)
【问题讨论】:
-
可能我不明白你的问题是什么,但我对你的两个例子都没有问题。但是我在
C中编译时重现了第二个错误,但它在C++中编译并成功执行 -
如果你的结构只有一个成员 - 不完整的数组(例如
int ar[]或char ar[]),你的 c++ 会编译吗?如果是这样,那么c和c++之间存在差异,因为c中的flexible array member in a struct with no named members错误不会编译(可能是数组中缺少维度而没有在括号中定义其长度,但我怀疑在c++ 数组衰减到已知长度为 8 字节的指针) -
如果上述方法适用于 C++ 别担心 - 它不适用于 C 或 C++。您通过尝试将信息复制到
f.buf来调用未定义的行为,而它还没有分配任何内存。仅仅因为您没有观察未定义行为的故障并不意味着它可以正常工作。 -
"incomplete type is not allowed" 搜索该错误消息(尽管修复拼写)并阅读您找到的一些内容以了解其含义。
-
@AndrewHenle 是对的,但它可以在 C++ 中工作,因为 MS VisualStudio 编译器不使用标准,而是有自己的规则。
标签: c++ arrays c struct sizeof