如何初始化堆上的结构的const成员

use*_*344 38 c

我想在堆上分配一个结构,初始化它并从函数返回一个指向它的指针.我想知道在这种情况下我是否有办法初始化结构的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;
}
Run Code Online (Sandbox Code Playgroud)

我应该从中得出结论,在包含const成员的堆上分配和初始化结构是不可能的?

caf*_*caf 54

像这样:

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;
}
Run Code Online (Sandbox Code Playgroud)

(注意,与C++不同,不需要malloc在C中强制转换返回值,并且它通常被认为是错误的形式,因为它可以隐藏其他错误).

  • 请注意,在init初始化中使用.x和.y是C99,如果编译器不支持,当然可以使用unamed条目. (7认同)
  • +1用于澄清C和C++之间的"malloc". (4认同)
  • @kevinarpe:没关系,因为`sizeof`显式没有计算它的参数,所以仍然定义了表达式的行为. (3认同)
  • @self.:这里返回的指针所指向的对象实际上从未被定义过,因为它是由`malloc()`创建的。考虑到 `p` 也可以定义为 `void *p;`,而 `sizeof *p` 的两个实例都更改为 `sizeof init`。 (2认同)
  • @Ephemera:是的,它可以 - 在 x86-64 上使用最低优化级别的 gcc 会将上述函数编译成一个不调用 `memcpy()` 的函数。也就是说,一旦你调用了 `malloc()`,`memcpy()` 就不太可能成为问题。 (2认同)

Joh*_*ler 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;
}
Run Code Online (Sandbox Code Playgroud)