#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等等。
如果有理解不足或者不对之处,欢迎修正~
浙公网安备 33010602011771号