使用指针会导致分段错误

时间:2014-06-01 16:59:54

标签: c linux sockets

我有一个问题: 我尝试使用systemcall gethostname(char * name,size_t size)但我得到了一些我不明白的结果:

char *hostname;
gethostname( hostname, size );  //results in a segmentation error
gethostname( &hostname, size ); //works fine.

我为什么要使用&在这里签名? gethostname请求指针,但主机名已经是指针。 我只是偶然得到了结果,并且不知道为什么第一个电话不起作用。 对不起,如果这是一个愚蠢的问题。

[编辑] 答案是:hostname尚未分配任何内存,因此,gethostname尝试访问未分配的内存,从而引发了分段错误。 此外,第二个LOC也没有合法的工作,它覆盖了堆栈上的其他数据,因此破坏了它。 使用它的方法是首先分配一些内存,然后将其传递给gethostname systemcall。

感谢您的时间和信息! :)

3 个答案:

答案 0 :(得分:3)

gethostname希望您传递缓冲区以便写入。在C中,字符串被实现为一个字符数组,它可以衰减到指针到字符串中的第一个字符。

gethostname将执行的操作是将主机名放在您指定的缓冲区中,直到它写入size个字符。鉴于此,您需要为其写入一个有效的缓冲区。在您的示例中,尚未为指针分配任何内容,因此指针的值未定义,并且它指向内存中的随机位置。尝试取消引用该指针然后是未定义的,因此程序会出现段错误。

正如我所说,解决这个问题的方法是传入一个真实的存储区域。以下两种方法都有效:

char hostname[50];
gethostname(hostname, 50); // Valid as a char[] decays to char*
// ---------- OR ----------------
char hostname*;
hostname = malloc(sizeof(char)*50); // Actually give the pointer some storage.
gethostname(hostname, 50);

应该注意的是,它在你的第二个案例中偶然发挥作用。 char* hostname是存储在堆栈中的指针。然后,&hostname将获取指针 hostname的地址。由于hostname在堆栈上有一些有效的存储空间(用于存储它指向的地址),因此可以写入该地址,但是您将开始覆盖堆栈上的有用数据。这将破坏程序的状态,它可能崩溃或变得不稳定。

答案 1 :(得分:2)

实际“工作正常”行也不正确;它没有导致seg错误,但确实写入了指针实际所在的堆栈。在这种情况下,没有发生seg故障,因为它是有效的内存 - 但仍然是非法的,因为它会破坏你将添加到该程序的任何其他自动变量,并且这些变量会在使用后破坏名称。如其他人所示,分配真实空间以进行修复。

答案 2 :(得分:1)

应该为字符串主机名分配空间,除非这是在一个函数中,其中hostname是一个外部字符串(在另一个函数中声明),如Oli所指出的那样

char hostname[128];

gethostname(hostname, sizeof hostname);
printf("My hostname: %s\n", hostname);
相关问题