return 返回值有关问题

return 返回值问题
#include <stdio.h>

int *create_num();
void print(int *p);

int main()
{
int *p;
p = create_num();

printf("%d ", *(p+8)); 

printf("\n");

print(p);

return 0;
}

int *create_num()
{
int a[10] ={10,20,30,40,50,60,70,80,90,12};

return a;
}

void print(int *p)
{
for(int i = 0; i < 10 ; i++)
printf("%d ", *(p+i));
printf("\n");
}
按理局部指针返回会出错,程序运行输出 :
90
-858993460 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460 -85
8993460 8 1245056
Press any key to continue 为什么 90 会有效输出
return  指针

------解决方案--------------------
因为进入printf函数前,在执行*(p+8)的时候,该段内存还未被新数据覆盖
执行printf函数时,该段内存被printf函数传参和执行时的压栈行为所覆盖


------解决方案--------------------
内存释放但没清零,数组首址又返回了
------解决方案--------------------
不要返回自动变量的地址。
------解决方案--------------------
90 是不可靠的情况
就和 
int i;
printf("%d\n", i);
输出 4219064 
一样 

------解决方案--------------------
http://bbs.csdn.net/topics/390612796
------解决方案--------------------
这是你没有弄清楚自动变量和静态变量的区别.
程序顺序执行, 当执行到p = create_num();语句的时候程序会调用create_num()函数, 这个函数中的a属于自动变量, 首先为a[]分配内存, 当这个函数调用完了之后系统就将a[]中的内存全部释放. 既然已经全部释放了, a[]中的内容也就没有了, 也就成了垃圾值了. 所以当再次调用print{}函数的时候, p所指向的值都是垃圾值了.
你可以在create_num()函数中加入关键字static就OK了
int *create_num()
{
  static int a[10] ={10,20,30,40,50,60,70,80,90,12};
return a;
}

不理解的话再追问吧, 觉得好一定要给分我呀, 我是新人, 谢了!

------解决方案--------------------
引用:
Quote: 引用:

这是你没有弄清楚自动变量和静态变量的区别.
程序顺序执行, 当执行到p = create_num();语句的时候程序会调用create_num()函数, 这个函数中的a属于自动变量, 首先为a[]分配内存, 当这个函数调用完了之后系统就将a[]中的内存全部释放. 既然已经全部释放了, a[]中的内容也就没有了, 也就成了垃圾值了. 所以当再次调用print{}函数的时候, p所指向的值都是垃圾值了.
你可以在create_num()函数中加入关键字static就OK了
int *create_num()
{
  static int a[10] ={10,20,30,40,50,60,70,80,90,12};
return a;
}

不理解的话再追问吧, 觉得好一定要给分我呀, 我是新人, 谢了!
我的问题是为什么可以正确输出 *(p+8),自动指针变量不是会清内存么?

内存读写的一条经验原则是:除非必要,否则不要写内存。
自动变量(基本类型)在函数返回时(或是返回后)的“自动销毁”过程实际是平衡堆栈(add esp,xxx),而不是清零相应的内存。因而原来的值还会保留在堆栈里,只不过对于之后的过程而言,这些值都是“垃圾值”了