繁体   English   中英

打印inet_ntoa函数中的分段错误

[英]segmentation fault in printing inet_ntoa function

考虑以下程序:

#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()函数进行打印时却给出了分段错误。 有人可以澄清吗?

注意:我不熟悉所讨论的功能,但我的答案基于此说明本文档

将该函数替换为:

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个字节,否则您的代码会更糟。 通常,您应该使用sizeof表达式来计算要复制的数量。

然后,将该struct in_addr传递给inet_ntoa ,这是可以的。 在您的函数中, &pLocalHostAddress指向包含struct in_addr的缓冲区的指针的地址。 因此,您两次取消引用以获取结构。

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

如果将main的代码更改为inet_ntoa(*(struct in_addr *)&pLocalHostAddress) ,则您的代码似乎可以工作 ,但是实际上坚持使用这样的代码是一个坏主意。

我明白了,双重解引用是个问题,因为MM告诉“您的代码中有两个不同的变量,都名为pLocalHostAddress”。 以下程序正在运行:

#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(pLocalHostAddress);
      printf("ip address: %s\n",inet_ntoa(*(struct in_addr *)pLocalHostAddress));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM