gpt4 book ai didi

c - 伪装成 void 双指针的 void 指针

转载 作者:太空宇宙 更新时间:2023-11-04 08:49:05 24 4
gpt4 key购买 nike

我一直在思考。我没有找到任何直接回答这个问题的东西,但我想我知道答案;我只是想从一些更有经验的人那里得到一些意见。

已知:

空指针仅指向一个内存地址。它不包含类型信息。

一个 int 指针指向包含一个 int 的内存地址。它会将指向的内存地址中的任何内容读取为整数,而不管最初填充到地址中的是什么。

问题:

如果一个 void 双指针 void ** foo 指向动态分配的 void 指针数组

void ** foo = malloc(sizeof(void *) * NUM_ELEMENTS);

是真的吗,正如我所假设的那样,由于 void 指针的独特性质实际上缺少任何类型的信息,而不是 void ** foo 一个等效的语句将是

void * bar = malloc(sizeof(void *) * NUM_ELEMENTS);

而且当我通过分配特定类型使用间接访问时,例如 with

(有人指出我不能取消引用 void 指针。为了清楚问题的目的,将下一行更改为适合该信息)

int ** fubar = bar;

我会从空指针得到一个合适的指针,它只是表现像一个指针?

还是这一切都在我的脑海中?

最佳答案

允许将 malloc 的结果分配给 void * 对象,然后再将其分配给 int ** 对象。这是因为 malloc 的返回值无论如何都是 void * 类型,并且它保证适合分配指向具有基本对齐要求的任何类型对象的指针。

但是,这段代码:

#define NUM_ELEMENTS 1000
void *bar = malloc(sizeof(void *) * NUM_ELEMENTS);
int **fubar = bar;
*fubar = 0;

不保证 C 标准的工作;它可能有未定义的行为。其原因并不明显。 C 标准不要求不同类型的指针具有相同的大小。 C 实现可以将 int * 的大小设置为一百万字节,将 void * 的大小设置为四个字节。在这种情况下,为 1000 个 void * 分配的空间将不足以容纳一个 int *,因此对 *fubar 的分配未定义行为。通常,人们会以这种方式实现 C 只是为了证明一个观点。但是,在较小的范围内也可能出现类似的错误:在 C 实现中,不同类型的指针具有不同的大小。

指向一个对象类型的指针可以转换为指向另一个对象类型的指针,前提是该指针具有适合目标类型的对齐方式。如果是,则将其转换回产生具有原始值的指针。因此,您可以将指向 void * 的指针转换为指向 void 的指针并返回,也可以将指向 void * 的指针转换为指向 的指针>int * 和返回,前提是对齐方式合适(如果指针由 malloc 返回并且您没有使用具有扩展对齐方式的自定义对象,则对齐方式合适)。

通常,您不能使用指向对象类型的指针写入,然后使用指向不同对象类型的指针读取相同的字节。这违反了别名规则。一个异常(exception)是,如果其中一个指针指向字符类型。此外,许多 C 实现确实支持此类别名,但可能需要设置命令行选项才能启用此类支持。

禁止别名包括重新解释指针。考虑这段代码:

int a;
int *b = &a;
void **c = (void **) &b;
void *d = *c;
int *e = (int *) d;

在第四行,c 指向b 占用的字节,但是*c 试图将这些字节解释为无效 *。这不能保证有效,因此 d 获取的值不一定是指向 a 的指针,即使它被转换为 int *如最后一行。

关于c - 伪装成 void 双指针的 void 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20338147/

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