段错误(可能是由于转换)
我通常不会去 stackoverflow 查找 sigsegv 错误,但目前我已经用我的调试器做了我能做的一切。
函数完成后会抛出分段错误错误。我忽略了什么想法吗?我怀疑这是由于将 sockaddr 转换为 sockaddr_in 造成的,但我无法在那里找到任何错误。 (删除该行可以消除段错误 - 但我知道这可能不是这里的根本原因)。
// basic setup
int sockfd;
char str[INET_ADDRSTRLEN];
sockaddr* sa;
socklen_t* sl;
struct addrinfo hints, *servinfo, *p;
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
// return string
string foundIP;
// setup the struct for a connection with selected IP
if ((rv = getaddrinfo("4.2.2.1", NULL, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return "1";
}
// loop through all the results and make a socket
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("talker: socket");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "talker: failed to bind socket\n");
return "2";
}
// connect the UDP socket to something
connect(sockfd, p->ai_addr, p->ai_addrlen); // we need to connect to get the systems local IP
// get information on the local IP from the socket we created
getsockname(sockfd, sa, sl);
// convert the sockaddr to a sockaddr_in via casting
struct sockaddr_in *sa_ipv4 = (struct sockaddr_in *)sa;
// get the IP from the sockaddr_in and print it
inet_ntop(AF_INET, &(sa_ipv4->sin_addr), str, INET_ADDRSTRLEN);
printf("%s\n", str);
// return the IP
return foundIP;
}
I don't normally go to stackoverflow for sigsegv errors, but I have done all I can with my debugger at the moment.
The segmentation fault error is thrown following the completion of the function. Any ideas what I'm overlooking? I suspect that it is due to the casting of the sockaddr to the sockaddr_in, but I am unable to find any mistakes there. (Removing that line gets rid of the seg fault -- but I know that may not be the root cause here).
// basic setup
int sockfd;
char str[INET_ADDRSTRLEN];
sockaddr* sa;
socklen_t* sl;
struct addrinfo hints, *servinfo, *p;
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
// return string
string foundIP;
// setup the struct for a connection with selected IP
if ((rv = getaddrinfo("4.2.2.1", NULL, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return "1";
}
// loop through all the results and make a socket
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("talker: socket");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "talker: failed to bind socket\n");
return "2";
}
// connect the UDP socket to something
connect(sockfd, p->ai_addr, p->ai_addrlen); // we need to connect to get the systems local IP
// get information on the local IP from the socket we created
getsockname(sockfd, sa, sl);
// convert the sockaddr to a sockaddr_in via casting
struct sockaddr_in *sa_ipv4 = (struct sockaddr_in *)sa;
// get the IP from the sockaddr_in and print it
inet_ntop(AF_INET, &(sa_ipv4->sin_addr), str, INET_ADDRSTRLEN);
printf("%s\n", str);
// return the IP
return foundIP;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
只是补充一下,valgrind 在检测未初始化的指针或任何与指针相关的错误方面非常有用。
just to add, valgrind is pretty useful in detecting uninitialized pointers or for that matter any pointer related errors.
在将
sa
传递给getsockname
之前,您没有分配它,因此您实际上在其中传递了一些垃圾指针值。它需要是:You did not allocate
sa
before passing it togetsockname
, so you effectively passed in some garbage pointer value there. It needs to be:您似乎从未将指针
sa
初始化为指向有效的sockaddr
(或sockaddr_in
)对象。如果您替换
为
并将
sa
的所有使用替换为&addr
您应该处于更好的状态。sl
也是如此。至少根据我的 getsockname 的文档,socklen_t*
参数需要指向一个有效的socklen_t
对象,该对象初始化为地址缓冲区的字节大小。例如
,使用
&slen
而不是sl
。It doesn't look like you ever initialize the pointer
sa
to point at a validsockaddr
(orsockaddr_in
) object.If you replace
with
and replace all uses of
sa
with&addr
you should be in better shape.The same is also true of
sl
. At least according to the documentation for my getsockname thesocklen_t*
parameter needs to point at a validsocklen_t
object initialized to the size in bytes of the address buffer.E.g.
and use
&slen
instead ofsl
.在我看来,您似乎从未将 sa 指针设置为实际指向任何东西。注释掉“struct sockaddr_in *sa_ipv4 = (struct sockaddr_in *)sa;”行应该会导致编译错误,所以我想我可以看到无法编译程序也会导致它不出现段错误 - 不存在的二进制文件很难崩溃:)
It looks to me like you don't ever set up the sa pointer to actually point at anything. Commenting out the line "struct sockaddr_in *sa_ipv4 = (struct sockaddr_in *)sa;" should cause a compile error, so I guess I can see how not being able to compile your program would also cause it to not segfault - hard for a non-existent binary to crash :)