我有一个大对象,有几个字段,这些字段是 const 数组,看起来像这样:
struct test {
const int vals[99999999];
};
我想使用指定的初始化程序来创建结构,因为真正的结构有很多字段。
结果我试了一下
#include <stdlib.h>
struct test {
const int vals[99999999];
};
int main()
{
struct test first = {.vals[4]=4};
return 0;
}
毫不奇怪,这会在运行时失败,因为结构太大,无法放入堆栈。
然后我尝试了
#include <stdlib.h>
struct test {
const int vals[99999999];
};
int main()
{
struct test * t = malloc(sizeof(struct test));
*t = (struct test){.vals[4]=4 };
return 0;
}
当我编译它时,这反而失败了:
test.c:9:8 error: assignment of read-only location '*t'
是否可以使用指定的初始化器来创建这个结构?
最佳答案
不,当然不是不放弃 const
。
您不能说“无法将此成员分配给”,然后在没有收到警告的情况下继续分配给它。
我让这个工作:
struct test *t = malloc(sizeof *t);
memcpy(t, &(struct test) { .vals[4] = 4 }, sizeof *t);
但我真的不认为它更好;它可能花费同样多,因为被复制的值必须存在于某个地方(我们正在复制 *t
的完整大小,毕竟它包括所有巨大的数组)。
也许最好切换到全局预初始化版本,您可以根据需要访问它:
static const struct test test_template = { .vals[4] = 4; };
然后你可以做例如:
struct test foo = test_template;
这是有效的,因为它是初始化而不是赋值。通过将其设为全局,它将大的“模板对象”插入全局数据,即离开堆栈。
对于堆分配的实例,您可以:
struct test * const foo = malloc(sizeof *foo);
memcpy(foo, &test_template, sizeof test_template);
这将覆盖vals
中的const
数据,这可能不是很漂亮但应该是安全的。我想。
我之前曾尝试使用初始化函数,但这是错误的,因为它分配给了 vals
。对不起!
关于c - 堆对象的指定初始化器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40359060/