#include "stdio.h"
#include "string.h"

//extern char * getname();

int main(int argc, const char *argv[])
{
    char * name1 = NULL;
    char name2[64] = "";
    name1 = getname();
    printf("2     %p\n",name1);

    memcpy(name2 , name1 , 64);
    printf("%s\n",name2);
    return 0;
}
#include "stdio.h"

char * getname()
{
    char name[32] = "helloworld";
    printf("1   %p\n",name);

    return name;
}

最后运行结果为

 

代码片段1和代码片段2分别归属于两个不同的.c文件,本实验可以看出,在代码片段1中,在没有声明getname()的条件下,直接使用getname()函数,程序编译会出现警告,但不会报错,但程序运行的结果是段错误。段错误多为内存不当操作造成的,比如空指针、野指针的读写操作,数组越界访问,破坏常量等。在本实验中,造成段错误的原因是函数在没有声明的情况下直接使用,此时编译系统默认函数返回值为int型。
将name地址和name1的地址打印出来:
name = 0x7ffe119392e0
name1 = 0x119392e0
很明显看出,getname()return前name的地址要比main函数中的name1的要长。
在64位操作系统中,8进制正式的写法是0x0123456789abcdef,一个数代表4位,一字节为8位,所以两个数代表一个字节。
其实name的真正地址应该是name = 0x00007ffe119392e0,
name1= 0x00000000119392e0
在64位操作系统中,char *(所有指针)为8字节,而int型为4字节,所以事实上getname()本应该返回的是8字节地址,但由于未被声明,因此编译系统默认返回的是4字节的int型非法地址,此时如果不对这个非法地址进行操作时,程序是正常的,如果对这个非法地址进行了操作,就会出现段错误,比如printf、memcmp等等。

 

 

如果有理解不足或者不对之处,欢迎修正~