Как инициализировать константные члены структур в куче
Я хотел бы выделить структуру в куче, инициализировать ее и вернуть указатель на нее из функции. Я задаюсь вопросом, есть ли способ для инициализации константных элементов структуры в этом сценарии:
#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?
Ответы
Ответ 1
Так же:
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;
}
(Обратите внимание, что в отличие от С++ нет необходимости отбрасывать возвращаемое значение malloc
в C, и его часто считают плохим, потому что он может скрыть другие ошибки).
Ответ 2
Если это 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;
}
Ответ 3
Если вы настаиваете на сохранении const в структуре, вам нужно будет сделать какое-то литье, чтобы обойти это:
int *cheat_x = (int *)&p->x;
*cheat_x = 3;
Ответ 4
Мне нравится кафе-подход, но это тоже произошло со мной.
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;
}