以下C程序尝试获取并打印当前RHEL主机的主机名。它会在此计算机上抛出segmentation fault
。根据{{3}}的定义,我应该能够传递一个char指针,不应该吗?
当我使用char数组时(如char hname[255]
),对gethostname
的调用有效。 (如果我这样做,我将如何将数组返回到main?)
#include <stdio.h>
#include <unistd.h>
char * fetchHostname()
{
// using "char hname[255]" gets me around the issue;
// however, I dont understand why I'm unable to use
// a char pointer.
char *hname;
gethostname(hname, 255 );
return hname;
}
int main()
{
char *hostname = fetchHostname();
return 0;
}
输出:
pmn@rhel /tmp/temp > gcc -g test.c -o test
pmn@rhel /tmp/temp >
pmn@rhel /tmp/temp > ./test
Segmentation fault
pmn@rhel /tmp/temp >
答案 0 :(得分:3)
正如gethostname
男子所说:
gethostname()函数应返回标准主机名 当前的机器。 namelen参数应该 指定name参数指向的数组的大小。 返回的名称应为空终止,除了 如果namelen的长度不足以保存主机名, 然后返回的名称将被截断,它是 未指定返回的名称是否以空值终止。
您需要一个存储函数信息的位置,因此将hostname声明为数组,而不是指针。
#include <unistd.h>
char * fetchHostname(char *hostname, int size)
{
// using "char hname[255]" gets me around the issue;
// however, I dont understand why I'm unable to use
// a char pointer.
gethostname(hostname, size);
return hostname;
}
int main()
{
char hostname[HOST_NAME_MAX + 1];
fetchHostname(hostname, HOST_NAME_MAX);
return 0;
}
答案 1 :(得分:3)
当我使用char数组时(如char hname [255]),调用 gethostname有效。 (如果我这样做,我将如何返回数组 主?)
将指针从main()
传递给您的函数。请注意,此方法使您的函数fetchHostname()
只是函数gethostname()
的包装器:
#include <stdio.h>
#include <unistd.h>
void fetchHostname(char *hname)
{
gethostname(hname,255);
}
int main()
{
char hostname[256];
fetchHostname(hostname);
return 0;
}
或者通过声明你的hname[]
数组本地静态,所以即使在程序离开函数之后它也是有效的(这种方法不是线程安全的):
#include <stdio.h>
#include <unistd.h>
char *fetchHostname (void)
{
static char hname[256];
gethostname(hname,255);
return hname;
}
int main()
{
char *hostname;
hostname = fetchHostname();
return 0;
}
答案 2 :(得分:2)
更新:请参阅@Tio Pepe的回答。
您需要在数组中分配空间(静态或动态):
char hname[HOST_NAME_MAX + 1];
否则你传递的是一个未经初始化的指针,它可以指向任何地方。
您对gethostname()的调用:
gethostname(hname, 255);
是一个合同,它说这是一个指向至少255个字符的已分配空间的指针。
此外,您正在尝试返回指向堆栈上分配的空间的指针。那不好。
如果要返回字符数组,Yoi需要动态分配字符数组。
char * hname;
hname = malloc((HOST_NAME_MAX +1) * sizeof(char));
但请注意,您现在必须管理何时释放该空间。
答案 3 :(得分:2)
虽然有很多技术上正确的答案,但我认为他们并没有真正向你解释你哪里出错了。
gethostname(char *name, size_t len);
已记录here,它基本上表示参数name
是您已分配的字符数组,此函数将复制主机名成。你如何做到这一点在这里的许多其他精彩答案中都有解释。
这就是为什么如果您自己制作数组但如果只是给它一个指针就会导致分段错误的原因。
此外,你给这个函数一个未初始化的指针,所以当它试图将数据复制到该地址(这只是内存中的一些完全随机的位置)时,它导致程序终止,因为它试图在其中写一个字符串是不允许的。
这种类型的错误告诉我你需要了解实际上是什么指针,并且你需要了解它们可以用来允许函数以与使用{{1}不同的方式返回值。声明。
答案 4 :(得分:1)
返回指向局部变量的指针是未定义的行为,因为它将超出范围。如果在堆上分配它(通过动态分配),则不会出现此问题。
char * fetchHostname()
{
char* hname= malloc(sizeof(char) * 256);
gethostname(hname, 255);
return hname;
}
int main()
{
char *hostname = fetchHostname();
printf(hostname);
free(hostname);
return 0;
}
答案 5 :(得分:0)
char *hname; //defined inside a function and would be destroyed after the function is executed
执行fetchHostname()后,返回主机名的地址无效,并且访问它会导致分段错误