c-指针分配和内存位置



在微处理器中,据说局部变量存储在堆栈中。在我的例子中,如果func1((被主函数调用,那么局部变量(int a=12;(将在堆栈中创建。一旦调用函数被执行,并返回到主函数,堆栈内存将被删除。因此指针地址仍然保持(*b(值12。在堆栈中,如果这个"a=12"被删除,那么"b"应该是一个悬空指针否??有人能解释一下吗?如果您对执行此代码时内存中发生的情况有详细的解释,那将很有帮助。

#include <stdio.h>
int* func1(void);
int main()
{
int* b = func1();
printf("%dn",*b);
}
int* func1(void)
{
int a = 12;
int* b = &a;
return b;
}

指针悬空。内存可能仍然保存以前的值,但取消引用指针会调用未定义的行为。

如果您通过-Wall选项,GCC将对此发出警告。

来自C标准(6.2.4(:

对象的生存期是在该存储被保证为其保留。对象存在,具有恒定地址,25(并保留其最后存储的值26(如果一个对象在其生命周期之外被引用终身,行为是未定义的。指针的值变为当它指向的对象到达其末端时不确定一生

这里有多个层。

首先,是C编程语言。这是一种语言。你在里面说些什么,它就有意义。有些句子是有意义的,但你也可以构建语法有效的胡言乱语句子。

你发布的代码,语法有效,是胡言乱语。当函数返回时,func1中的对象a停止存在。*b尝试访问一个不再存在的对象。它没有定义在对象的生存期结束后访问对象时应该发生什么。您可以阅读有关未定义行为的信息。

内存存在。当函数返回时,它并不是被分解的。RAM芯片并不是从你的电脑里掉出来的。它们仍然在那里。

因此,编译器将生成一些机器指令。将执行这些机器指令。仅取决于编译器的决定(代码是未定义的行为,编译器可以随心所欲(,实际代码可以以编译器决定的任何方式进行行为。但是,最有可能的是,*b将生成机器指令,读取对象a所在的内存区域。该存储器区域可能仍然保持值12,或者它在返回func1和调用printf之间的某个地方被覆盖,导致读取一些其他值。

在堆栈中,如果删除了这个"a=12",那么"b"应该是一个悬空指针否?

是。

当此代码时,内存中会发生什么

这取决于编译器生成的实际机器指令。编译代码并检查程序集。

严格来说,行为是未定义的,但在printf之后重复printf或以其他方式检查(例如在调试器中(*b。很可能它将不再是12

说堆栈存储器是"非易失性"是不准确的;删除";。相反,堆栈指针会恢复到调用之前的地址。内存在其他方面是未受影响的,但可供后续调用使用(或用于向此类调用传递参数(,因此在调用printf之后,它很可能已被重用和修改。

所以是的,指针是";悬挂的";因为它指向的是不再是"0"的存储器;有效的";从某种意义上说,它不属于指针所在的上下文。

相关内容

  • 没有找到相关文章

最新更新