C程序运行崩溃,面试题,求大神解释解决思路

C程序运行崩溃,面试题,求大神解释

#include<string.h>

int main()
{
char a;
char *str=&a;
strcpy(str,"hello");
puts(str);
return 0;
}
------解决思路----------------------
你的str指向了a,a只有一个字节,.....溢出了,可能出错也可能不出错,
------解决思路----------------------
只分配一个字节,空间不足,应该这样修改:

#include<stdio.h>

int main()
{
    char a[10];
    char* str = (char*)a;

    strcpy(str, "hello");
    puts(str);

    return 0;
}

------解决思路----------------------
使用了非法内存,你只有一个字符(1B)是申请的,可以合法使用,而后面你使用了多个空间,因此崩溃!
------解决思路----------------------
这是一个典型的栈溢出问题。

C语言运行时内存分为2块,堆内存和栈内存。所有的函数在发生调用关系时,会自动在栈内存上进行展开,就是生成一些数据,我们称之为上下文,展开的地址顺序很奇怪,是由高址向低地址空间展开的。

运行时发生函数调用时,栈上会存放一些数据,这些数据分为2个部分。在这里,你可以认为函数调用就是一个超级版本的goto语句,它跳到被调用函数的首地址,等执行完了,再跳回来。

为了完成整个过程,编译器需要建立上下文,比如,传给被调用函数的参数,最重要的是,被调用函数执行完之后,它返回的地址。这些都是数据,存储在栈上。这是第一部分的数据。另一部分数据,则是被调用函数在执行过程中,自己生成的一些临时变量,比如LZ提供的代码中的变量: char a; char* str;

现在我们再看LZ提供的如下代码语句:
strcpy(str,"hello");

显然,地址越界了,现在的a 的值应该是'h',然后呢,‘ello’这四个字节就把一些其它的内存覆盖了,最大的可能性就是覆盖了main函数的返回地址。现在,当程序返回后,发现所在的指令地址在一个莫名其妙的地方,如果你的运气不错,这个地方不是可执行区域,那么操作系统会为你捕获这个异常,引发一个访址异常,程序崩溃。如果你的运气比较糟糕,这仍然是一个可执行区域,那么,恭喜你,You have been hacked!