【问题标题】:Why getaddrinfo( ) always cause segmentation fault?为什么 getaddrinfo() 总是导致分段错误?
【发布时间】:2020-07-16 00:09:41
【问题描述】:
#include <string.h>
#include <stdio.h>
#include <netdb.h>

int main(){
    char buff[50];
    char port[5];

    printf("Enter address to lookup: ");
    fgets(buff, 50, stdin);

    printf("Enter Port: ");
    fgets(port, 5, stdin);

    struct addrinfo* res;
    struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_flags= AI_PASSIVE;

    __auto_type error = getaddrinfo(buff, port, &hints, &res);
    if (error < 0 )
        return 4;

    printf("Host IP: %s", buff);
    error = getnameinfo(res->ai_addr, res->ai_addrlen, buff, 50, 0, 0, 0);
    if (error < 0)
        return 5;

    printf("Host IP: %s", buff);
    freeaddrinfo(res);
}

运行此代码导致 getaddrinfo( ) 由于分段错误而终止程序。 编辑:检查getaddrinfo的返回值后,错误似乎来自getaddrinfo(),输入只是 www.google.com(还有一堆其他地址也测试过了) 443(也用80端口试过)

【问题讨论】:

  • 您的意见是什么?对于初学者,添加错误检查代码。检查所有函数的返回值 - 不应该在不知道它是否包含有效指针的情况下盲目地取消引用 res。不应盲目假设buff 包含有效字符串而不检查函数返回值。
  • @kaylum 我的输入只是带有端口 443 的 www.google.com 我知道错误检查,但是这段代码非常简单,它应该可以正常工作,但有些地方不对。
  • 您的问题是您将&amp;res 传递给getaddrinfo。但是,res 是一个 unitialized 指针。试试:struct addrinfo res;(即没有*)。而且,如果您这样做,请将所有 res-&gt; 更改为 res.
  • @CraigEstey 实际上 getaddinfo( ) 应该分配结构并将指针分配给 res 根据文档
  • “它应该可以正常工作”。好吧,显然不是。只需添加错误检查。所有好的代码都需要它,它将帮助您调试可能存在的任何问题。您不能只说“它应该可以工作”而不进行基本调试,例如错误检查、调试打印、在调试器中运行等。

标签: c networking segmentation-fault getaddrinfo getnameinfo


【解决方案1】:

当我运行您的原始代码时,我得到一个 res0x1

问题在于 buffport 字符串中有一个换行符 (\n)。

当换行符被剥离时,它会运行到完成。

这是我使用的修改后的代码:

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <netdb.h>

void
fixup(char *buf)
{
    char *cp;

    cp = strchr(buf,'\n');
    if (cp != NULL)
        *cp = 0;
}

int
main()
{
    char buff[50];
    char port[5];

#if 1
    FILE *xf = stdin;
#else
    FILE *xf = fopen("input.txt","r");
#endif

    printf("Enter address to lookup: ");
    fgets(buff, 50, xf);
    fixup(buff);

    printf("Enter Port: ");
    fgets(port, 5, xf);
    fixup(port);

    struct addrinfo *res;
    struct addrinfo hints;

    memset(&hints, 0, sizeof(hints));
    hints.ai_flags = AI_ALL;

    getaddrinfo(buff, port, &hints, &res);
    printf("res=%p\n",res);
    printf("Host IP: %s\n", buff);

    getnameinfo(res->ai_addr, res->ai_addrlen, buff, 50, 0, 0, NI_NUMERICHOST);
    printf("Host IP: %s\n", buff);

    freeaddrinfo(res);
}

【讨论】:

  • 所以整个问题是 getaddrinfo 不能处理 '\n' 字符,这似乎有点奇怪吧:)。
  • @KhaledGaber 它可能会更好地保护自己。但是,getaddrinfo 的速度并不是“面向人”(即它假设其输入已经过检查)。
猜你喜欢
  • 1970-01-01
  • 2020-09-15
  • 2012-04-19
  • 2011-05-20
  • 1970-01-01
  • 1970-01-01
  • 2019-12-08
相关资源
最近更新 更多