1

可能重复:
为什么结构的 sizeof 不等于每个成员的 sizeof 之和?

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

typedef struct student
{

int roll_no;
char* name;
int* pointer;


}student;

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

4

5 回答 5

1

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

typedef 对对齐没有影响——它只是为某个对象创建一个“速记引用”,可能就像一个结构。您可以将 typedef 视为同义词。

于 2013-02-04T03:58:54.153 回答
1

name确实没有与struct: 一起存储,只存储了一个指向的指针。数据通常在其struct自身之外的区域中动态分配。

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

于 2013-02-04T04:00:07.753 回答
0

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

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

1000 roll_no
1004 name
1008 pointer

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

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

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

于 2013-02-04T03:59:52.080 回答
0

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

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

于 2013-02-04T04:00:57.080 回答
0

实际上在结构中

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

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

  • 的 4 个字节int,后跟
  • 4 字节char *指向name的指针,后跟
  • 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;

这里的字符串在内存中的某个地方——正如你注意到的,它是在结构之前声明的。假设它的内存位置是0x12345678是在0x20000000,结构是在 0x22222222 所以我们有

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

您会看到结构是0F000000for 1512345678用于字符串地址和20000000用于地址。

于 2013-02-04T04:16:18.417 回答