如何为结构中的typedef分配内存(C)

时间:2013-02-04 03:54:26

标签: c typedef

  

可能重复:
  Why isn’t sizeof for a struct equal to the sum of sizeof of each member?

在C中创建结构时,例如:

typedef struct student
{

int roll_no;
char* name;
int* pointer;


}student;

我注意到roll_no和name没有连续存储在内存中。这是如何运作的?如果目的是封装这些数据,那么它们是否连续存储会更好吗?编译器如何知道这些数据属于一起?

5 个答案:

答案 0 :(得分:1)

编译器对齐结构的每个元素的开头以匹配体系结构的要求。 这通常意味着对齐位于单词边界上,但没有严格的规则。

typedef对齐无效 - 它只是创建一个对象的“速记引用”,可能就像一个结构。您可以将typedef视为同义词。

答案 1 :(得分:1)

name确实没有与struct一起存储:只存储指针。数据通常在struct本身以外的区域动态分配。

要将名称与struct一起存储,您需要将其作为数组。这种方法的缺点是字符串必须是固定长度的(即所有struct s将分配足够的name最大长度的内存量,或者您需要使用灵活的数组元素通过在name[]的末尾声明struct数组。最后一种方法的缺点是(1)分配变得更加复杂,(2)你不能创建这样的数组{ {1}} s,以及(3)结构中只能有一个灵活的数组。

答案 2 :(得分:0)

它们是连续存储的。只是char *名称中包含的地址在其他地方。要在内存中连续存储,请使用数组而不是指针。

这是它存储在内存中的方式,例如,struct的地址从1000(十进制)开始。

1000 roll_no
1004 name
1008 pointer

name和pointer是指针,因此它们将保存malloc分配的值(地址)。

s->name = malloc(100);
s->pointer = malloc(4);

在这种情况下,没有结构填充,因为所有都是整数(甚至是指针),这意味着它们是体系结构寄存器大小的大小(通常为32或64位)。

答案 3 :(得分:0)

数据是连续存储的,但由于优化和对齐字边界,可能会出现整体数据。对齐取决于您运行的处理器和选择的编译器选项。 (包装)

编译器将计算结构的偏移量,因此它可以在内存中进行查找以获取结构的元素。

答案 4 :(得分:0)

实际上在 struct

struct student
{
  int roll_no;
  char* name;
  int* pointer;
}

C完全符合您的要求(除了“结构填充”,但这是另一个故事)。假设英特尔处理器上有gcc,结构由

组成
  • int的4个字节,后跟
  • 指向 name char *指针的4个字节,后跟
  • 4个字节的int *指针指向指针

name 成员是一个指向char(s)的指针,通常是指向内存中某个字符串的指针。例如

char *string = "John Doe";
int value = 255;
struct student me;

me.roll_no = 15;
me.name = string;
me.pointer = &value;

这里 string 在内存中的某个位置 - 正如您所注意到的那样,它在结构之前已经被声明了。假设其内存位置为0x12345678位于0x20000000,结构位于0x22222222,因此我们有

0x12345678 : John Doe\0
...
0x20000000 : FF000000  // 255
...
0x22222222 : 0F0000001234567820000000

您看到0F000000的结构为15字符串地址为12345678值为 20000000地址。