C结构中char*和char[]的区别

3

当我想在C结构中存储动态数据数组时,有两种编写方法:

typedef struct {
   int row;
   int col;
   char* data;
} item1;

或者

typedef struct {
   int row;
   int col;
   char data[];
} item2;

这两种方法都可以工作。但是在我的64位Mac OSX上,使用gcc Apple LLVM版本5.1(clang-503.0.38),它们之间存在一些差异:

      sizeof(item1) is 16
      sizeof(item2) is 8

为什么会有差异?除此之外,这两个实现还有什么区别吗?
完整的测试代码如下:
#include <stdio.h>

typedef struct {
  int row;
  int col;
  char* data;
} item1;


typedef struct {
  int row;
  int col;
  char data[];
} item2;


int main() {
  printf("%d %d\n", sizeof(item1), sizeof(item2));
  return 0;
}

输出结果为:
16 8

1
可能是重复问题:- https://dev59.com/NXI-5IYBdhLWcg3wu7FU - user3414693
没有提供item1item2typedef也不完整,两者似乎有关联。 - Utkan Gezer
1
typedef仍然不完整,这种情况下像sizeof(item1)这样的调用是无法工作的。 - Utkan Gezer
2
请复制并粘贴您的确切代码。 - Keith Thompson
我删除了我的回答。@ThoAppelsin是正确的。sizeof在这里不起作用。你发布了一些其他的代码。 - haccks
显示剩余3条评论
2个回答

6

指针的大小是机器特定的(无论是32位还是64位)。在32位机器上,结果分别为128字节。对于64位机器,答案将是168字节。
请参见解释。

typedef struct {
   int row;         // 4 bytes
   int col;         // 4 bytes
   char* data;      // 4/8 bytes on 32/64-bit machine
}item1 ;  

在32/64位机器上,总大小为12/16字节。

typedef struct {
   int row;         // 4 bytes
   int col;         // 4 bytes
   char data[];     // 0 bytes --> Flexible array 
}item2 ;  

总大小 = 8个字节。

为什么可变数组的大小是0

C11:6.7.2.1(p18)

[...] 特别地,如果省略可变数组成员,则结构的大小就相当于省略了它 [...]


1
4+4+4=12。你是不是少了点什么?xD - James Hunt
@JamesHunt; 是的。我错过了 :) - haccks
我认为64位的16字节是一个不错的经验法则,但值得注意的是,这个答案说它可以通过编译器设置和编译指示进行控制,因此可能并非总是如此。 - weston

1
typedef struct item2 {
   int row;
   int col;
   char data[];
}

在这个结构体中,item2有两个整数,所以在大多数系统中大小将为2 * sizeof(int),同时我们有一个未定义大小的数组char data[],所以在这种情况下它计为零。我认为如果在结构体中有填充,则数组存储的元素数量将与填充相关,但我不确定。

总共8字节。

typedef struct item1 {
   int row;    
   int col;
   char* data;
}

在这个结构体中,我们有2个整数,表示8个字节由整数占用,在64位系统中还有一个指针,表示另外8个字节。
总共16个字节。
有一些你需要知道的事情,这种情况下没有填充,也没有在item2中。而char* data;char data[];之间的区别是,后者是一个将在堆栈中分配的数组,而前者是在堆栈中分配的指针,通常与来自堆的动态内存一起使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接