如何在C中初始化const中的const(使用malloc)

yas*_*sar 21 c malloc struct initialization constants

我试过了;

void *malloc(unsigned int);
struct deneme {
    const int a = 15;
    const int b = 16;
};

int main(int argc, const char *argv[])
{
    struct deneme *mydeneme = malloc(sizeof(struct deneme));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是编译器的错误:

gereksiz.c:3:17: error: expected ':', ',', ';', '}' or '__attribute__' before '=' token
Run Code Online (Sandbox Code Playgroud)

而且,这也是;

void *malloc(unsigned int);
struct deneme {
    const int a;
    const int b;
};

int main(int argc, const char *argv[])
{
    struct deneme *mydeneme = malloc(sizeof(struct deneme));
    mydeneme->a = 15;
    mydeneme->b = 20;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是编译器的错误:

gereksiz.c:10:5: error: assignment of read-only member 'a'
gereksiz.c:11:5: error: assignment of read-only member 'b'
Run Code Online (Sandbox Code Playgroud)

而且都没有汇编.有没有办法在使用malloc分配内存时初始化struct中的const变量?

Chr*_*odd 27

你需要抛弃const来初始化malloc结构的字段:

struct deneme *mydeneme = malloc(sizeof(struct deneme));
*(int *)&mydeneme->a = 15;
*(int *)&mydeneme->b = 20;
Run Code Online (Sandbox Code Playgroud)

或者,您可以创建结构的初始化版本并将其memcpy:

struct deneme deneme_init = { 15, 20 };
struct deneme *mydeneme = malloc(sizeof(struct deneme));
memcpy(mydeneme, &deneme_init, sizeof(struct deneme));
Run Code Online (Sandbox Code Playgroud)

如果你经常这样做,你可以使deneme_init静态和/或全局(所以它只需要构建一次).


使用C11标准引用解释为什么此代码不是一些注释所建议的未定义行为:

  • 此代码不违反6.7.3/6,因为返回的空间malloc不是" 使用const限定类型定义的对象".表达式mydeneme->a不是对象,而是表达式.虽然它具有const-qualified类型,但它表示一个未使用const限定类型定义的对象(实际上,根本没有定义任何类型).

  • 写入由分配的空间永远不会违反严格别名规则malloc,因为每次写入都会更新有效类型(6.5/6).

(malloc但是,通过读取分配的空间可以违反严格的别名规则).

在Chris的代码示例中,第一个设置整数值的有效类型,int第二个设置有效类型const int,但是在两种情况下继续读取这些值*mydeneme是正确的,因为严格别名规则(6.5/7 bullet 2)允许通过表达式读取对象,该表达式与对象的有效类型相同或更有资格.由于表达mydeneme->a具有类型const int,它可以被用来读取有效类型的对象intconst int.

  • 否 - 如果所讨论的内存不是const(例如从malloc返回的内容),则定义良好.如果您尝试通过强制转换修改const对象,则仅定义它. (9认同)
  • *非常*未定义. (8认同)
  • 是不是const-cast访问未定义的行为? (7认同)

小智 10

你试过这样做:

int main(int argc, const char *argv[])
{
    struct deneme mydeneme = { 15, 20 };
    struct deneme *pmydeneme = malloc(sizeof(struct deneme));
    memcpy(pmydeneme, &mydeneme , sizeof(mydeneme));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我没有测试,但代码似乎是正确的