c - 打印 inet_ntoa 函数中的段错误

标签 c sockets host gethostbyname

考虑以下程序:

#include <sys/socket.h> 
#include <stdio.h> 
#include <netinet/in.h>
       #include <arpa/inet.h>
       #include <string.h>
#include <netdb.h> 

void printhost(char* pLocalHostAddress )
{
   struct hostent * pHost;
   struct in_addr   **pptr;
   char hostName[128]="\0";

   gethostname(hostName, sizeof(hostName)); 
   printf("%s",hostName);
   if( NULL != (pHost = gethostbyname(hostName)) )
   {
      memcpy( pLocalHostAddress, *pHost->h_addr_list, 4);
      printf("ip address: %s\n",inet_ntoa(**(struct in_addr **)&pLocalHostAddress));
   }
}
void main()
{
   char pLocalHostAddress[50];
   printhost((char *)pLocalHostAddress);
           printf("ip address: %s\n",inet_ntoa(**(struct in_addr **)&pLocalHostAddress));

}

奇怪的是,当我尝试在 printhost() 函数内打印时,它正确打印主机 IP 地址,但当我尝试从 main() 打印时,它会出现段错误功能。有人可以澄清一下吗?

最佳答案

注意:我不熟悉相关功能,但我的答案基于 this explanationthis documentation .

将函数替换为:

struct in_addr *printhost(void)
{
// ... 
    if( NULL != (pHost = gethostbyname(hostName)) )
    {
        struct in_addr *tmp = (struct in_addr *)*pHost->h_addr_list;
        printf("ip address: %s\n",inet_ntoa(*tmp));
        return tmp;
    }
    return NULL;
}

并这样调用它:

struct in_addr *p = printhost();
if ( p )
    printf("ip address: %s\n",inet_ntoa(*p));
<小时/>

您的代码会通过多种方式导致未定义的行为。当未定义的行为被触发时,任何事情都可能发生,包括相同的代码似乎在一个地方工作而在另一个地方不起作用。分析得太深入是没有用的,最好还是修复一下代码。

memcpy( pLocalHostAddress, *pHost->h_addr_list, 4);复制 struct in_addr 的前 4 个字节进入 main 中 50 字节缓冲区的开头。我假设sizeof(struct in_addr)在您的系统上实际上是 4 个字节 as suggested by this page否则你的代码会更糟糕。一般来说,您应该使用 sizeof表达式来计算要复制的数量。

然后你就通过了struct in_addrinet_ntoa没关系。在你的函数中,&pLocalHostAddress指向包含struct in_addr的缓冲区的指针的地址。因此,您取消引用两次来获取结构。

但是在 main , &pLocalHostAddress是包含 struct in_addr缓冲区的地址。所以你应该只取消引用一次。相反,您的代码尝试将互联网地址解释为指针的字节,从而在取消引用该指针时导致段错误。

如果您更改 main 中的代码,您的代码可能看起来可以工作inet_ntoa(*(struct in_addr *)&pLocalHostAddress) ,但是实际坚持使用这样的代码并不是一个好主意。

关于c - 打印 inet_ntoa 函数中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32518045/

相关文章:

C 编程多线程段错误

sockets - 如何在 Haskell 中从 Socket 读取字节

c - 帮忙解决以下情况

php - MySqli 无法连接到本地主机

c - 初始化代码放在哪里更好,在循环之前还是在循环内部?

c - 两个条件如何在 if-ifelse-else 语句中起作用?

c - 需要一些帮助以完成作业

c# - C#通过套接字高效传输屏幕的改进方法

bash - 在远程 Linux 主机上执行本地脚本

macos - 有没有人设置tomcat来使用mod_jk运行虚拟主机