奇怪的行为在c

时间:2012-09-17 16:25:34

标签: c arrays pointers

  

可能重复:
  Can a local variable's memory be accessed outside its scope?

我最近遇到了以下代码:

#include <stdio.h>

int* abc () {
   int a[3] = {1,10,100};
   return a;
}
int* xyz () {
   int b[1] = {222};
   return b;
}
int main() {
   int *a, *b;
   a = abc();
   b = xyz();
   printf("%d\n", *a);
   return 0;
}

输出为222'a'指向xyz()内声明的数组。

我的问题是:

  1. 为什么指向xyz()内声明的数组。

  2. 在函数xyz()内声明的数组在执行函数后应该超出范围。为什么没有发生?

6 个答案:

答案 0 :(得分:8)

2: 正在发生,整个程序有未定义的行为。这不是一个正确的程序,对于ifs和buts几乎没有什么意义。

答案 1 :(得分:3)

您可能会看到 222 ,因为abc中用于本地数组的内存已被用于其他内容 - 函数xyz的堆栈。而你正在传递一个地址到那个记忆中。再做一些函数调用,*a可能包含其他一些值。

  执行该函数后,

应超出范围。为什么没有发生?

变量超出范围。在函数外使用该地址是不正确的代码:使用指向函数返回的本地数据的指针是未定义的行为。

答案 2 :(得分:2)

变量ab是自动变量;在另一个函数中使用它们的地址是一种未定义的行为。任何事情都可能发生:你不能指望输出(例如,优化编译器可以删除一些非法代码)。

答案 3 :(得分:1)

要返回指针,它必须是指向动态分配的变量或静态或全局变量的指针。

返回指向堆栈变量的指针将使您拥有指向堆栈的指针,当您调用新方法时,该指针将被重用。

在你的情况下,重复使用堆栈变量为另一个数组并覆盖调用第一个方法时存储的旧值。

尝试再次调用printf,您会看到不同的输出,因为第一次调用printf会改变堆栈内容。

答案 4 :(得分:0)

  

为什么没有发生?

它确实发生了,只是正式的。未定义的行为没有义务崩溃或行为不端 - 他们&#34;任何可能发生的事情&#34;意味着它也可以在没有任何错误的情况下运行。 I just answered a similar question.

答案 5 :(得分:0)

函数abcxyz分别将地址传递回本地创建的数组。后续调用正在混合以前使用过的内存(并传回给您)。

这些称为自动局部变量。

您需要将这些数组声明为静态或以不同的方式分配内存。