首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C- addrinfo -指针分割错误

C- addrinfo -指针分割错误
EN

Stack Overflow用户
提问于 2015-11-26 12:17:41
回答 2查看 263关注 0票数 1

C- addrinfo -指针分割错误

我有一个分割错误;我做了一个奇怪的修复,但我仍然很担心,因为我不知道问题是什么。任何洞察力都是惊人的!在最后一个代码块中工作“修复”!

试图使用target_addrinfo绑定时发生的分段错误:

代码语言:javascript
复制
struct addrinfo *my_server_res;
struct addrinfo *their_server_res;

int main(int argc, char **argv) {
//........
    set_addrinfo();
    handle_binding();
}

void set_addrinfo() {
    int status;
    struct addrinfo hints;
    struct addrinfo *target_addrinfo; // fix (1/3): **target_addrinfo
    char ipstr[INET6_ADDRSTRLEN];

    // THIS IS TRUE, takes my_server_res
    // fix(2/3): (l ? &my_server_res : &their_server_res)
    target_addrinfo = (l ? my_server_res : their_server_res); 

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    char *node;
    node = (l ? "localhost" : host_name);

    // fix (3/3) 3rd argument: target_addrinfo
    if ((status = getaddrinfo(node, port, &hints, &target_addrinfo)) != 0) {
        fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
        exit(1);
    }

}

void handle_binding() {
    struct addrinfo *target_addrinfo;
    // THIS IS TRUE, takes my_server_res
    target_addrinfo = (l ? my_server_res : their_server_res);
    int b_res = bind(sockfd, target_addrinfo->ai_addr, target_addrinfo->ai_addrlen);
    if (b_res == -1) {
        perror("__Bind");
        exit(1);
    }
}

堆栈跟踪:再次尝试使用my_server_res时出现的问题?:

代码语言:javascript
复制
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401e16 in handle_binding () at ncTh.c:385
385     int b_res = bind(sockfd, target_addrinfo->ai_addr, target_addrinfo->ai_addrlen);
(gdb) backtrace
#0  0x0000000000401e16 in handle_binding () at ncTh.c:385
#1  0x0000000000401cad in setup_socket () at ncTh.c:330
#2  0x0000000000401ad0 in main (argc=6, argv=0x7fffffffdea8) at ncTh.c:266
(gdb) frame 0
#0  0x0000000000401e16 in handle_binding () at ncTh.c:385
385     int b_res = bind(sockfd, target_addrinfo->ai_addr, target_addrinfo->ai_addrlen);
(gdb) 

工作“修复”,更改为set_addrinfo():

代码语言:javascript
复制
struct addrinfo **target_addrinfo; // was *target_addrinfo
char ipstr[INET6_ADDRSTRLEN];

target_addrinfo = (l ? &my_server_res : &their_server_res); // was my_server_res : their_server_res

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;

char *node;
node = (l ? "localhost" : host_name);
                               // 3rd argument was &target_addrinfo :
if ((status = getaddrinfo(node, port, &hints, target_addrinfo)) != 0) {
    fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
    exit(1);
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-11-26 12:46:29

在原代码中:

代码语言:javascript
复制
struct addrinfo *target_addrinfo;
target_addrinfo = (l ? my_server_res : their_server_res);

这会将指针my_server_res的值复制到target_addrinfo中。

代码语言:javascript
复制
getaddrinfo(node, port, &hints, &target_addrinfo)

这会将指向target_addrinfo的指针(指向指针的指针)传递给函数getaddrinfo,然后函数getaddrinfo通过执行等效的*&target_addrinfo = new_ptr为其分配一个新的值。这个新值是指向getaddrinfo正在为您检索的信息的指针。

所有这一切对my_server_res没有任何影响,它仍然保持原值,很可能为NULL。

在新的守则中:

代码语言:javascript
复制
struct addrinfo **target_addrinfo;
target_addrinfo = (l ? &my_server_res : &their_server_res);

这会将指向my_server_res的指针复制到target_addrinfo (现在是指向指针的指针)。

代码语言:javascript
复制
getaddrinfo(node, port, &hints, target_addrinfo)

这会将target_addrinfo (当前是指向my_server_res的指针)的值传递给函数getaddrinfo,然后getaddrinfo通过执行与*target_addrinfo = new_ptr等价的操作为其分配一个新的值。my_server_res现在包含指向getaddrinfo正在为您检索的信息的指针。

票数 2
EN

Stack Overflow用户

发布于 2015-11-26 13:02:42

您可能会陷入target_addrinfo问题的取消引用,我发布了以下代码。(总比不迟到好:)

代码语言:javascript
复制
struct addrinfo *my_server_res;
struct addrinfo *their_server_res;

struct addrinfo **target_addrinfo; //this should be global 

int main(int argc, char **argv) {
//........
    set_addrinfo();
    handle_binding();
}

void set_addrinfo() {
    int status;
    struct addrinfo hints;

    char ipstr[INET6_ADDRSTRLEN];

    // THIS IS TRUE, takes my_server_res
    target_addrinfo = (l ? &my_server_res : &their_server_res); //set it once here

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    char *node;
    node = (l ? "localhost" : host_name);
    if ((status = getaddrinfo(node, port, &hints, &target_addrinfo)) != 0) {
        fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
        exit(1);
    }

}

void handle_binding() {
    //target_addrinfo should be initialized in set_addrinfo()
    int b_res = bind(sockfd, 
        (*target_addrinfo)->ai_addr,    // don't forget to dereference target_addrinfo, here
        (*target_addrinfo)->ai_addrlen); // and here

    if (b_res == -1) {
        perror("__Bind");
        exit(1);
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33938527

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档