【发布时间】:2013-06-05 11:32:57
【问题描述】:
int main()
{
struct a
{
struct a *next;
struct a *prev;
};
struct a *A[2];
printf("Address of (&(A[0])->next) = %p",(&(A[0])->next));
getch();
return 0;
}
在上面的 printf 语句中,我正在访问“struct a”结构的“next”指针,当我在开发编译器中运行程序时,它给了我有效的内存地址(尽管我还没有为它分配任何内存)。解释为什么会发生这种情况将非常有帮助。
是否为“下一个”和“上一个”字段分配了内存?
【问题讨论】:
-
但它是正确的内存地址吗?不,AFAICS 你正在取消引用一个未初始化的指针,所以如果它有效,那就是侥幸。请注意,您实际上并没有为 As 分配任何内存——您是在告诉它您有一个指向 As 的指针数组。您分配的唯一内容是存储这些指针的内存。
-
它可能会一直发生,是的,例如它重用了以前指向某个 init 结构或堆栈上其他位置的堆栈帧的某些部分。但是不能保证会有一个有效的指针,如果你例如使用大多数编译器在调试模式下编译它会将堆栈初始化为无效指针,例如像 0xCCCCCCCC 这样的奇数,肯定会失败。
-
printf-statement 本身非常有效,但是您尝试打印的数据却不是。取消引用统一化的指针将导致undefined behaviour,这可能会导致程序可能做你想做的事,但它们也可能让你的猫着火。 -
@Rup 我认为这种侥幸每次都在发生。 + 如果我将 printf 修改为 printf("Address of (&(A[0])->next) = %p", (((struct a *)(&(A[0])))->next) );侥幸永远不会发生