[英]C - addrinfo - pointers segmentation fault
C - addrinfo - pointers segmentation fault C - addrinfo - 指针分割故障
I'm getting a segmentation fault; 我遇到了分段错误; I made a weird fix but I'm still worried because I can't figure out what the problem was. 我做了一个奇怪的修复,但我仍然担心,因为我无法弄清楚问题是什么。 Any insight would be amazing! 任何见解都会令人惊叹! Working "fix" in the last code block! 在最后一个代码块中“修复”!
segmentation fault when trying to bind using target_addrinfo: 尝试使用target_addrinfo绑定时出现分段错误:
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);
}
}
stack trace: problem when trying to use my_server_res again?: 堆栈跟踪:尝试再次使用my_server_res时出现问题?:
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)
working "fix", changes to set_addrinfo(): 工作“修复”,更改为set_addrinfo():
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);
}
In the original code: 在原始代码中:
struct addrinfo *target_addrinfo;
target_addrinfo = (l ? my_server_res : their_server_res);
This copies the value of the pointer my_server_res
into target_addrinfo
. 这target_addrinfo
指针my_server_res
的值复制到target_addrinfo
。
getaddrinfo(node, port, &hints, &target_addrinfo)
This passes a pointer to target_addrinfo
(a pointer to a pointer) into the function getaddrinfo
which then assigns a new value to it, by doing the equivalent of *&target_addrinfo = new_ptr
. 这会将指向target_addrinfo
(指向指针的指针)的指针传递给函数getaddrinfo
,然后通过执行等效于*&target_addrinfo = new_ptr
的函数为其分配新值。 This new value is a pointer to the information getaddrinfo
is retrieving for you. 这个新值是指向getaddrinfo
正在为您检索的信息的指针。
All this has no effect on my_server_res
which remains with its original value, likely NULL. 所有这些对my_server_res
没有影响, my_server_res
保留其原始值,可能为NULL。
In the new code: 在新代码中:
struct addrinfo **target_addrinfo;
target_addrinfo = (l ? &my_server_res : &their_server_res);
This copies a pointer to my_server_res
into target_addrinfo
(which is now a pointer to a pointer). 这target_addrinfo
指向my_server_res
的指针复制到target_addrinfo
(现在是指向指针的指针)。
getaddrinfo(node, port, &hints, target_addrinfo)
This passes the value of target_addrinfo
(which is currently a pointer to my_server_res
) into the function getaddrinfo
which then assigns a new value to it, by doing the equivalent of *target_addrinfo = new_ptr
. 这会将target_addrinfo
(当前是指向my_server_res
的指针)的值传递给函数getaddrinfo
,然后函数getaddrinfo
通过执行等效的*target_addrinfo = new_ptr
为其分配新值。 my_server_res
now contains a pointer to the information getaddrinfo
is retrieving for you. my_server_res
现在包含一个指向getaddrinfo
正在为您检索的信息的指针。
you will probably fall in dereferencing of target_addrinfo
problem, i posted this code. 你可能会解除对target_addrinfo
问题的解除引用,我发布了这段代码。 (better late then never :)) (晚了好然后再:))
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);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.