gpt4 book ai didi

C 字符数组作为指针

转载 作者:太空狗 更新时间:2023-10-29 15:04:30 25 4
gpt4 key购买 nike

我想了解:

  • 为什么有时会出现 char[1]在 C 中用作 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 指针...

最佳答案

这是一个 answer描述了 char[1] 技巧。基本上,想法是在 malloc()ing 结构时分配更多内存,以便在没有额外分配的情况下为您的字符串提供一些存储空间。有时您甚至可以看到 char something[0] 用于相同的目的,这更不直观。

On the other hand, treating this as a full blown char * doesn't work either, as can be seen with the test_s.b is output above, which should show a NULL pointer then...

如果某物是一个数组,它的名称和 &name 都只是给出指向 C 中数组开头的指针。无论它是结构中的成员还是独立的,这都有效变量。

printf("real sizeof(test_s.b): %lx \n", ((void *)(&test_s.b) - (void *)(&test_s.a)) );

此行给出了分配给 a 的空间大小,而不是此结构中的 b。在 b 之后放一些东西并用它来减去。使用 packed 属性(这意味着您不允许编译器混淆对齐等),您应该得到 1。

#include <stdio.h>
#include <string.h>

struct test_struct {
char *a;
char b[1];
char c;
} __attribute__((packed));

int main() {
struct test_struct s;
printf("%lx\n", ((void*)&s.c) - ((void*)&s.b));
return 0;
}

我得到 1

关于C 字符数组作为指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12863527/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com