struct hack with pointer而不是array

时间:2014-02-15 08:35:28

标签: c struct

以下制作可变大小结构的方法有什么问题?

  struct tode{
      int g;
      int *p;
  };

  struct tode *lp = malloc(sizeof(struct tode) + (10 * sizeof(int)));

注意:这是完全错误的,但在我脑海中引起了混乱,所以试图讨论

3 个答案:

答案 0 :(得分:3)

结构中的

p是指向int的指针,而不是数组。所以它不会编译。您应该使用零长度数组或灵活数组成员为它动态分配内存。但是,它必须是最后一个结构成员。以下是您如何申报。

struct tode {
    int g;
    int p[]; // p is a zero length array here, not a pointer
};

// sizeof(tode) is 4 on a 32-bit machine

这是少数可以声明零长度数组的情况之一(其他我记得当你声明一个extern数组时)。由于零长度成员是不完整类型,因此必须先分配内存,然后才能对其进行任何操作。

struct tode *lp = malloc(sizeof(tode) + 10*sizeof(int));

// after you are done with lp

free(lp);

这里,10*sizeof(int)参数中的malloc部分动态分配数组。 sizeof(tode)未考虑p因为它是不完整的类型。 在上述声明之后,p是一个包含10 int s。

的数组

但是,如果你这样做了

struct tode {
    int g;
    int *p; // p is a pointer
};

// sizeof(tode) is 8 on a 32-bit machine

然后你会动态地将结构分配为

struct tode *lp = malloc(sizeof(tode));

// lp->p is of type (int *) so it can contain any int address

lp->p = malloc(10 * sizeof(int));

// after you are done with lp

free(lp->p);
free(lp);

您还可以使用designated initializer(C99)在堆栈上分配和初始化您的结构,如Jens所示

struct tode lv = {.g = 10, .p = malloc(10 * sizeof(int))}; 

但是,在变量lv超出范围之前,您应freelv.p指向的内存free(lv.p); 作为

{{1}}

答案 1 :(得分:2)

您有lp作为auto变量,因此您无法为其分配新地址,lp本身不是指针。正确的初始化如下所示:

struct tode lp = { .p = malloc(sizeof(int[10])) };

这不是struct hack,只是一个普通的指针成员。既然你无论如何处理这个地址,就没有办法让这个连续。

BTW:struct hack不是“ hack ”,它是C标准(正弦C99)的一部分,称为“灵活数组成员”。

答案 2 :(得分:0)

如果要使变量缓冲区结构使用数组作为最后一个元素而不是指针。或者适当地分配指针变量的地址,使其指向已分配的内存。

例如,您的代码p将具有任意随机值。但是你希望它是lp + sizeof(lp->g)(为了简单起见,请保留任何填充问题)。

因此,您应该将其定义为,并根据需要扩展p

struct tode{
      int g;
      int p[1];
  };
相关问题