【发布时间】:2012-10-12 16:40:47
【问题描述】:
我想了解:
- 为什么有时 C 中的
char[1]被用作char*(为什么这样做?)和 - 内部如何工作(发生了什么)
给出以下示例程序:
#include <stdio.h>
#include <string.h>
struct test_struct {
char *a;
char b[1];
} __attribute__((packed)); ;
int main() {
char *testp;
struct test_struct test_s;
testp = NULL;
memset(&test_s, 0, sizeof(struct test_struct));
printf("sizeof(test_struct) is: %lx\n", sizeof(struct test_struct));
printf("testp at: %p\n", &testp);
printf("testp is: %p\n", testp);
printf("test_s.a at: %p\n", &test_s.a);
printf("test_s.a is: %p\n", test_s.a);
printf("test_s.b at: %p\n", &test_s.b);
printf("test_s.b is: %p\n", test_s.b);
printf("sizeof(test_s.b): %lx \n", sizeof(test_s.b));
printf("real sizeof(test_s.b): %lx \n", ((void *)(&test_s.b) - (void *)(&test_s.a)) );
return 0;
}
我得到以下输出(OS X,64 位):
sizeof(test_struct) is: 9
testp at: 0x7fff62211a98
testp is: 0x0
test_s.a at: 0x7fff62211a88
test_s.a is: 0x0
test_s.b at: 0x7fff62211a90
test_s.b is: 0x7fff62211a90
sizeof(test_s.b): 1
real sizeof(test_s.b): 8
查看内存地址,可以看到即使结构体有 9 个字节大,也分配了 16 个字节,这似乎是由char b[1] 引起的。但我不确定这些额外的字节是否是由于优化/内存对齐原因而分配的,或者这是否与 C 对 char 数组的内部处理有关。
一个真实世界的例子可以在<fts.h>看到:
`man 3 fts` 将结构成员 `fts_name` 显示为:
char *fts_name; /* file name */
而 /usr/include/fts.h 将成员定义为:
char fts_name[1]; /* file name */
最后,fts_name 真的可以用作指向 C 字符串的指针。例如,使用printf("%s", ent->fts_name) 打印到标准输出就可以了。
所以如果char[1] 真的是一个字节大,它就不能在我的 64 位机器上用作内存指针。另一方面,将其视为完整的char * 也不起作用,正如上面的test_s.b is 输出所示,它应该显示一个NULL 指针......
【问题讨论】:
-
主要思想:我会让你失望,但指针不是数组。
-
real sizeof(test_s.b): 8错误。因为sizeof(char*)是8而sizeof(char)是1。这就是为什么你的结构是 9 字节。 -
阅读comp.lang.c FAQ的第6节;这是对 C 中数组和指针之间(通常令人困惑的)关系的出色解释。