首页 > 解决方案 > 在初始化期间将值分配给动态分配的结构的常量成员

问题描述

我有一个点结构:

struct Point 
{
    const int x; 
    const int y;
};

在我的代码中,我有很多这样的点,所以我想创建指向它们的指针,这样我在处理它们时就不会看到它们被一遍又一遍地复制。

知道您可以像这样初始化结构的常量成员:

struct Point my_point = { .x = 1, .y = 2};

我以为我可以对动态分配的结构做同样的事情。但似乎并非如此:

struct Point *point = malloc(sizeof(struct Point));

*point = (struct Point){.x = 1, .y = 2}; 

但是我得到

main.c: In function ‘main’:
main.c:23:8: error: assignment of read-only location ‘*point’
 *point = (struct Point){.x = 1, .y = 2};

使用 GCC 7.1.1 时。在铿锵声我得到

prog.c:23:8: error: cannot assign to lvalue with const-qualified data member 'x'
*point = (struct Point){.x = 1, .y = 2}; 
~~~~~~ ^
prog.c:14:15: note: data member 'x' declared const here
    const int x; 
    ~~~~~~~~~~^
prog.c:15:15: note: data member 'y' declared const here
    const int y;
    ~~~~~~~~~~^
1 error generated.

有没有办法做到这一点?

例子

#include <stdio.h>
#include <stdlib.h>

struct Point 
{
    const int x; 
    const int y;
};


int main()
{
    struct Point *point = malloc(sizeof(struct Point));

    *point = (struct Point){.x = 1, .y = 2}; 
    return 0;
}

标签: cpointers

解决方案


我真的找不到解决这个问题的好方法。在 C++ 中,您可以使用构造函数和私有成员来解决这个问题。

但是你可以使用memcpy这是安全的

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Point {
    const int x; 
    const int y;
};

int main(void){
    struct Point *p = malloc(sizeof *p);
    memcpy(p, &(struct Point) {.x=1, .y=2 }, sizeof *p);

    printf("%d %d\n", (*p).x, (*p).y);
}

可以为此使用变量:

int x=1; int y=2;
memcpy(p, &(struct Point) {.x=x, .y=y }, sizeof *p);

如果您正在使用gcc,则可以使用编译器扩展:

memcpy(p, &(typeof(*p)) {.x=1, .y=2 }, sizeof *p);

但我确实希望在大多数情况下,以下方法会是更好的方法:

struct Point 
{
    int x; // Remove const here
    int y;
};

int main(void) 
{
    // Allocate and assign a non const object
    struct Point *tmp_ptr = malloc(sizeof *tmp_ptr);
    *tmp_ptr = (struct Point) {.x=1, .y=2};

    // Create a new const pointer
    const struct Point *p = tmp_ptr;

    // This will invoke compiler error
    (*p).x = 42;
}

推荐阅读