如何解决在初始化期间为动态分配的结构的常量成员分配值
我有一个指向结构:
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时。在c里我得到
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;
}
解决方法
我真的看不出解决这个问题的好方法。在C ++中,您可以使用构造函数和私有成员解决此问题。
但是您可以使用memcpy
,which is safe:
#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,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;
}
,
最好的解决方案是对结构进行整体限定,而不是对单个成员进行限定。您可以将分配和初始化包装在“构造函数”中,该构造函数返回一个只读指针:
typedef struct
{
int x;
int y;
} point_t;
const point_t* point_create (void)
{
point_t* obj = malloc(sizeof *obj);
if(obj == NULL)
return NULL;
*obj = (point_t){.x = 1,.y = 2};
return obj;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。