为什么这段代码给出了意想不到的输出。返回地址C
int * func(int *xp)
{
int y = 10 + *xp;
return (&y);
}
void main()
{
int x = 10;
int *xp = func(&x);
printf("%d\n", x);
printf("%d\n", *xp);
}
预期输出:
10
20
实际产出:
10
1074194112
为什么这段代码给出了意想不到的输出。返回地址C
int * func(int *xp)
{
int y = 10 + *xp;
return (&y);
}
void main()
{
int x = 10;
int *xp = func(&x);
printf("%d\n", x);
printf("%d\n", *xp);
}
预期输出:
10
20
实际产出:
10
1074194112
你是返回一个指针变量(y
),其超出范围你离开func
的时刻。这是未定义的行为。
这是不完全清楚你想达到什么目的,但有几个方法来解决这个问题:
int
的价值;*xp
到位,不返回任何东西;int*
参数并将结果存储在那里(再次返回void
);malloc
或new
分配堆上的内存,并返回(调用者将负责正确释放该内存)。这是不可能说出了上述的适用于您的问题不知道的大背景下。
最后,main()
should return int
(谢谢@pmg发现这个)。这与您遇到的问题无关,但值得指出。
我们要求对此进行变更以面试候选人。 – user47559
因为函数返回时y超出范围。请记住,y是在堆栈中声明的。这是一个未定义的行为。
返回局部变量的地址,然后解除它导致未定义的行为。
由于printf
调用使用与func
相同的内存(堆栈)区域,因此它们会用它们自己的内部变量和函数参数覆盖func
的堆栈帧。
为了解决这个问题,在堆与malloc
分配内存:
int* func (int *xp) {
int* res = malloc(sizeof(int));
if (!res) {
perror('Cannot allocate memory in func');
exit(1);
}
*res = 10 + *xp;
return res;
}
不要忘记free
它:
int main(void) {
int x = 10;
int *xp = func(&x);
printf("%d\n", x);
printf("%d\n", *xp);
free(xp);
return 0;
}
< real_life_example>
想象一下,你把一个苹果放在桌子上。然后你写下它在一张纸上的位置。后来,有人来吃苹果。现在纸上的位置没有意义。
</real_life_example>
......并且你可以在同一个地方抓住一个香蕉,让别人放在桌子上。 – phihag
他他他...我喜欢你的评论。 –
将“香蕉”替换为“充满刀片的苹果”,更像是你的代码中发生了什么...... :-) –
func
应该是这样的:
// C++
int* func(int* xp)
{
int* y = new int;
*y = 10 + *xp;
return y;
}
正如大家已经提到的,你试图返回一个临时变量的地址。没有人提到过最简单的解决方案。在该函数内将该变量作为静态投射。这使得它保留在整个程序的内存中。
int * func(int *xp)
{
static int y;
y = 10 + *xp;
return (&y);
}
void main()
{
int x = 10;
int *xp = func(&x);
printf("%d\n", x);
printf("%d\n", *xp);
}
这个按预期工作。当然,有更好的方法可以解决这个问题,但如果你确实想在函数范围内声明一个变量并返回它的地址,这是最简单的解决方案。请记住,每次调用这个函数时,它都会修改y,它不会给你一个副本。
'无效main' ** ARRRRRRRRGGGGGGGGHHHHHHHH!** – pmg
样的一个常见问题。参见[埃里克利珀的解释(http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope/6445794#6445794)。 1851 upvotes和计数... – eran
@pmg最新的问题与无效主???当编译器没有给出任何错误,那么为什么你worrie? –