指针分配和内存位置
在微处理器中,局部变量存储在堆栈中。在我的例子中,如果 func1() 由 main 函数调用,则局部变量 (int a = 12;) 将在堆栈中创建。一旦被调用函数执行并返回主函数,堆栈内存将被删除。所以指针地址仍然保存(*b)值12。在堆栈中,如果删除这个“a = 12”,那么“b”应该是一个悬空指针,不是吗?谁能解释一下吗?如果您对执行此代码时内存中发生的情况有详细的解释,那将会很有帮助。
#include <stdio.h>
int* func1(void);
int main()
{
int* b = func1();
printf("%d\n",*b);
}
int* func1(void)
{
int a = 12;
int* b = &a;
return b;
}
In an Microprocessor it is said that the local variables are stored in stack. In my case if func1() is called by main function then the local variable (int a = 12;)will be created in stack. Once the Called Function is executed the and return back to main function the stack memory will be deleted. So the pointer address still holds (*b) the value 12. At stack if this 'a = 12' is deleted then 'b' should be a dangling pointer no?? Can anyone explain this ? If you have detailed explanation on what happens in memory when this code is being executed it would be helpful.
#include <stdio.h>
int* func1(void);
int main()
{
int* b = func1();
printf("%d\n",*b);
}
int* func1(void)
{
int a = 12;
int* b = &a;
return b;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
指针悬空。内存可能仍保留先前的值,但取消引用指针会调用未定义的行为。
如果您传递
-Wall
选项,GCC 将向您发出警告。来自 C 标准 (6.2.4):
The pointer is dangling. The memory may still hold the previous value, but dereferencing the pointer invokes undefined behaviour.
GCC will give you a warning about this, if you pass
-Wall
option.From the C standard (6.2.4):
这里有多层。
首先是C编程语言。它是一种语言。你在里面说一些东西,它就有意义。有些句子是有意义的,但你也可以构建语法上有效的无意义句子。
您发布的代码在语法上是有效的,但却是胡言乱语。当函数返回时,
func1
内的对象a
将停止存在。*b
尝试访问不再存在的对象。没有定义当您在对象的生命周期结束后访问对象时会发生什么。您可以阅读有关未定义行为的信息。记忆是存在的。它不像函数返回时就解体了。 RAM 芯片不会从您的 PC 中掉落。他们还在那里。
所以你的编译器会产生一些机器指令。这些机器指令将被执行。 完全取决于您的编译器决策(代码是未定义的行为,编译器可以执行其想要的操作),实际代码可以按照编译器决定的任何方式运行。但是,最有可能的是,
*b
将生成机器指令来读取对象a
所在的内存区域。该内存区域可能仍保存值12
,或者它可能在func1
返回和调用之间的某个位置被覆盖。 code>printf
,导致读取一些其他值。是的。
这取决于编译器生成的实际机器指令。编译代码并检查程序集。
There are multiple layers here.
First, is the C programming language. It is a language. You say stuff in it and it has meaning. There are sentences that have meaning, but you can also construct grammatically valid sentences that are gibberish.
The code you posted, grammatically valid, is gibberish. The object
a
insidefunc1
stops existing when the function returns.*b
tries to access an object that does not exists anymore. It is not defined what should happen when you access an object after its lifetime ended. You can read about undefined behavior.Memory exists. It's not like it is disintegrated when a function returns. It's not like RAM chips are falling out of your PC. They are still there.
So your compiler will produce some machine instructions. These machine instructions will execute. Depending solely on your compiler decisions (the code is undefined behavior, compiler can do what it wants) the actual code can behavior in any way the compiler decides to. But, most probably,
*b
will generate machine instructions that will read the memory region where objecta
resided. That memory region may still hold the value12
or it may have been overwritten somewhere betweenfunc1
returning and callingprintf
, resulting in reading some other value.Yes.
This depends on the actual machine instructions generated by the compiler. Compile your code and inspect the assembly.
严格来说,行为是未定义的,但在
printf
之后重复printf
或以其他方式检查(例如在调试器中)*b
。它很可能不再是12
。说堆栈内存被“删除”是不准确的。相反,堆栈指针将恢复到调用调用之前的地址。否则,内存不会被触及,但可供后续调用使用(或用于向此类调用传递参数),因此在调用 printf 后,它很可能已被重用和修改。
所以是的,指针是“悬空”的,因为它指向的内存不再“有效”,因为它不属于指针存在的上下文。
Strictly speaking, the behaviour is undefined, but repeat the
printf
or otherwise inspect (in your debugger for example)*b
after theprintf
. It is likely that it will no longer be12
.It is not accurate to say that the stack memory is "deleted". Rather the stack pointer is restored to the address it had before the call was invoked. The memory is otherwise untouched but becomes available for use by subsequent calls (or for passing arguments to such calls), so after calling
printf
it is likely to have been reused and modified.So yes, the pointer is "dangling" since it points to memory that is no longer "valid" in the sense that it does not belong to the context in which the pointer exists.