指针算术和动态内存?

4
以下代码片段的含义是什么?
int* pointer = malloc (sizeof(int) + 3);
pointer++;

分配的内存块无法被拆分成 sizeof(int) 的块。所以当指针要跳到下一个“块”时会发生什么?这是否已经定义好了呢?


@TimCooper 是的,但指针现在指向什么? - dfg
@BrainSteel 我不明白。你能否详细说明一下? - dfg
这可能是在具有4字节整数的机器上未定义的行为...因为你并不拥有所有的内存。对于之前的评论感到抱歉,我没有正确阅读问题。 - BrainSteel
它没有“定义”。实际上,malloc的空间几乎肯定会“舍入”为8或16的倍数,因此对增加后的指针的访问不会“跨越”堆分配,但从技术上讲,您不能依赖于这一点。(但是,一般来说,您可以不停地增加指针,只要不对它们进行解引用。在几乎所有环境中都是“安全的”,但可能不是严格意义上的“定义”)。 - Hot Licks
1
@BrainSteel 是正确的 - 但在 int 长度为四个字节的平台上,当访问这段内存时会遇到麻烦,因为 malloc 只为你分配了七个字节。但通常它会进行一些边界对齐,所以你可能会得逞。只要增加指针就是完全有效的。访问它指向的内存(你的代码片段没有这样做)是无效的。 - Floris
3个回答

2

这段代码是有效的,但可能需要更多上下文才能理解。

第一行: malloc 分配的空间比一个 int 的大小大 3 个字节。这是有效的。

第二行: pointer++ 是有效的。它只是一个地址。

pointer 进行进一步的引用(例如加减或比较)是有效的。对其进行解引用(即 *pointer)将导致未定义的行为。

请注意,这 3 个“额外”的字节是有效的存储空间,可以使用 char * 等类型来访问。


@dfg,不是的。由于您将“pointer”声明为类型“int *”,因此“++”操作将始终按“sizeof int”递增“pointer”。这可能是4个字节。可能是8。它不会是3。例如,如果您想要指向那3个额外字节中的第一个字节的指针,则可以执行以下操作:“char *c =(char *)pointer +(sizeof int);”,然后“c”是一个指针,每次递增一个字节。希望这有所帮助。如果上面的答案有用,请将其标记为已接受。否则,请告诉我哪里不清楚。干杯。 - Darren Stone

0

指针可以用于指针比较(C标准允许指针超过最后一个元素一个位置)。读取或写入的访问是未定义的。


-1

*pointer 是由 3 个字节的 0 和 sizeof(int) - 3 个未定义的字节组成。哪些字节(与你的 int 相关的重要性)是未定义的,取决于平台的字节顺序,因此在你的 C 程序中,整个东西可能都是未定义的。


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