指针分配和内存位置

发布于 2025-01-10 01:43:18 字数 422 浏览 3 评论 0原文

在微处理器中,局部变量存储在堆栈中。在我的例子中,如果 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦纸 2025-01-17 01:43:18

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

如果您传递 -Wall 选项,GCC 将向您发出警告。

来自 C 标准 (6.2.4):

对象的生命周期是程序执行期间的部分
保证为其保留哪个存储空间。一个物体存在,
有一个常量地址,25) 并保留其最后存储的值
26) 如果一个对象在其外部被引用
生命周期,行为是未定义的。指针的值变为
不确定它所指向的对象何时到达其末尾
寿命。

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):

The lifetime of an object is the portion of program execution during
which storage is guaranteed to be reserved for it. An object exists,
has a constant address,25) and retains its last-stored value
throughout its lifetime.26) If an object is referred to outside of its
lifetime, the behavior is undefined. The value of a pointer becomes
indeterminate when the object it points to reaches the end of its
lifetime.

无远思近则忧 2025-01-17 01:43:18

这里有多层。

首先是C编程语言。它是一种语言。你在里面说一些东西,它就有意义。有些句子是有意义的,但你也可以构建语法上有效的无意义句子。

您发布的代码在语法上是有效的,但却是胡言乱语。当函数返回时,func1 内的对象 a 将停止存在。 *b 尝试访问不再存在的对象。没有定义当您在对象的生命周期结束后访问对象时会发生什么。您可以阅读有关未定义行为的信息。

记忆是存在的。它不像函数返回时就解体了。 RAM 芯片不会从您的 PC 中掉落。他们还在那里。

所以你的编译器会产生一些机器指令。这些机器指令将被执行。 完全取决于您的编译器决策(代码是未定义的行为,编译器可以执行其想要的操作),实际代码可以按照编译器决定的任何方式运行。但是,最有可能的是,*b 将生成机器指令来读取对象 a 所在的内存区域。该内存区域可能仍保存值12,或者它可能func1返回和调用之间的某个位置被覆盖。 code>printf,导致读取一些其他值。

在堆栈中,如果删除了“a = 12”,那么“b”应该是一个悬空指针,不是吗?

是的。

这段代码在内存中会发生什么

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

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 inside func1 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 object a resided. That memory region may still hold the value 12 or it may have been overwritten somewhere between func1 returning and calling printf, resulting in reading some other value.

At stack if this 'a = 12' is deleted then 'b' should be a dangling pointer no?

Yes.

what happens in memory when this code

This depends on the actual machine instructions generated by the compiler. Compile your code and inspect the assembly.

深白境迁sunset 2025-01-17 01:43:18

严格来说,行为是未定义的,但在 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 the printf. It is likely that it will no longer be 12.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文