我想在堆上分配一个结构,初始化它并从函数返回一个指向它的指针。我想知道在这种情况下我是否有办法初始化结构的const成员:
#include <stdlib.h>
typedef struct {
const int x;
const int y;
} ImmutablePoint;
ImmutablePoint * make_immutable_point(int x, int y)
{
ImmutablePoint *p = (ImmutablePoint *)malloc(sizeof(ImmutablePoint));
if (p == NULL) abort();
// How to initialize members x and y?
return p;
}
我应该从中得出结论,在包含const成员的堆上分配和初始化结构是不可能的吗?
答案 0 :(得分:53)
像这样:
ImmutablePoint *make_immutable_point(int x, int y)
{
ImmutablePoint init = { .x = x, .y = y };
ImmutablePoint *p = malloc(sizeof *p);
if (p == NULL) abort();
memcpy(p, &init, sizeof *p);
return p;
}
(注意,与C ++不同,不需要在C中转换malloc
的返回值,并且它通常被认为是错误的形式,因为它可以隐藏其他错误。)
答案 1 :(得分:11)
如果这是C而不是C ++,除了破坏类型系统外,我没有其他解决方案。
ImmutablePoint * make_immutable_point(int x, int y)
{
ImmutablePoint *p = malloc(sizeof(ImmutablePoint));
if (p == NULL) abort();
// this
ImmutablePoint temp = {x, y};
memcpy(p, &temp, sizeof(temp));
// or this
*(int*)&p->x = x;
*(int*)&p->y = y;
return p;
}
答案 2 :(得分:2)
如果你坚持将const保留在结构中,你将不得不做一些演员来解决这个问题:
int *cheat_x = (int *)&p->x;
*cheat_x = 3;
答案 3 :(得分:0)
我喜欢caf's approach,但这也发生在我身上
ImmutablePoint* newImmutablePoint(int x, int y){
struct unconstpoint {
int x;
int y;
} *p = malloc(sizeof(struct unconstpoint));
if (p) { // guard against malloc failure
*p.x = x;
*p.y = y;
}
return (ImmutablePoint*)p;
}