Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize const members of structs on the heap

Tags:

c

I would like to allocate a structure on the heap, initialize it and return a pointer to it from a function. I'm wondering if there's a way for me to initialize const members of a struct in this scenario:

#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;
}

Should I conclude from this that it is impossible to allocate and initialize a struct on the heap which contains const members?

like image 773
user268344 Avatar asked Feb 08 '10 00:02

user268344


4 Answers

Like so:

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;
}

(Note that unlike C++, there is no need to cast the return value of malloc in C, and it is often considered bad form because it can hide other errors).

like image 192
caf Avatar answered Oct 28 '22 23:10

caf


If this is C and not C++, I see no solution other than to subvert the type system.

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;
}
like image 36
John Knoeller Avatar answered Oct 28 '22 23:10

John Knoeller


If you insist on keeping the const in the structure, you are going to have to do some casting to get around that:

int *cheat_x = (int *)&p->x;
*cheat_x = 3;
like image 41
R Samuel Klatchko Avatar answered Oct 29 '22 01:10

R Samuel Klatchko


I like caf's approach, but this occured to me too

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;
}
like image 1
dmckee --- ex-moderator kitten Avatar answered Oct 29 '22 00:10

dmckee --- ex-moderator kitten