下面是用 C 编写的示例代码:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
int* second;
void myTest1(int a, bool check){
if(check){
second = &a;
}
printf("%d", *(second));
printf(" ");
}
int main(int argc, char const *argv[])
{
int a =1;
int b = 2;
int c=3;
myTest1(a,true);
myTest1(b,false);
myTest1(c,false);
}
我希望输出是这样的
1 1 1
但实际输出是
1 2 3
我对此有点困惑,void myTest1(int a, bool check)
在这里我相信a
应该有功能范围。但是似乎a
的内存位置在每个函数调用中重复使用。
我正在使用命令 gcc <filename>.c
进行构建
以下是一些系统详细信息:
最佳答案
您正在将 second
设置为函数调用结束时超出范围的变量地址。一旦变量超出作用域,它占用的内存就不再是你的了,可以重用。该内存地址恰好在每次后续调用中重复使用,并将新参数的值复制到其中。
不要存储局部变量的地址并在变量超出范围后访问该地址。这会产生未定义的行为。您不能对该指针的另一端可能有什么做出任何假设。
关于以下内容:
here I believed
a
should have function scope
确实...
But it seems that the memory location of "a" is reused in every function call.
嗯,重用是 a
具有“功能范围”的必然和自然结果。除非您假设某种垃圾收集行为,即保留指向此内存的指针会阻止它被重用,a
的内存位置应该被重用一次 a
是不可访问的,否则这就是内存泄漏的定义。如果不重用函数参数的内存,则每次函数调用都会有意地泄漏内存。
在 C 和 C++ 中,您的工作是不存储已超出范围的堆栈分配变量的地址(或者至少,不要在变量超出范围后尝试使用该地址)。将地址存储在指针中的行为并不能天生就保护该内存不被重用。您可以自行决定在堆上分配该内存并管理其生命周期,或者允许堆栈管理您的内存而不保留比它们指向的变量的生命周期更长的指针。
https://stackoverflow.com/questions/72902821/