c - 堆对象的指定初始化器

标签 c struct

我有一个大对象,有几个字段,这些字段是 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/

相关文章:

c - 错误 C2065 : 'i' : undeclared identifier when iterating in C

c - 成员之间不会有填充是否安全?

c - 将结构放入共享内存

c - 为什么 C 文件流的开头称为 `SEEK_SET` ?

c - 根据代码用C语言制作输入和输出文件?

c - 为什么 "typedef struct foo foo;"被认为是有害的?

c# - 为什么在调用非静态方法时会调用结构中的静态构造函数?

c++ - 在 Python 中调试 C 程序

c - 数组采用 union 结构的大小

c - 如何使新结构与旧结构兼容?