Segfault(可能由于铸造)

时间:2010-06-11 23:27:52

标签: c++ sigsegv segmentation-fault

我通常不会因为sigsegv错误而去stackoverflow,但我现在已经尽力使用我的调试器。

完成该功能后,将抛出分段错误错误。我忽略了什么想法?我怀疑这是因为将sockaddr投射到sockaddr_in,但我无法在那里发现任何错误。 (删除该行可以摆脱seg错误 - 但我知道这可能不是这里的根本原因。)

// 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;

}

4 个答案:

答案 0 :(得分:5)

看起来您似乎没有初始化指针sa以指向有效的sockaddr(或sockaddr_in)对象。

如果您更换

sockaddr* sa;

sockaddr addr;

并将sa的所有用途替换为&addr,您应该处于更好的状态。

sl也是如此。至少根据我的getsockname的文档,socklen_t*参数需要指向一个有效的socklen_t对象,该对象初始化为地址缓冲区的字节大小。

E.g。

socklen_t slen = sizeof addr;

并使用&slen代替sl

答案 1 :(得分:2)

在我看来,你似乎没有设置实际指向任何东西的sa指针。注释掉“struct sockaddr_in * sa_ipv4 =(struct sockaddr_in *)sa;”应该导致编译错误,所以我想我可以看到如何不能编译你的程序也会导致它不是段错误 - 对于不存在的二进制文件来说很难崩溃:)

答案 2 :(得分:1)

在将sa传递给getsockname之前,你没有分配struct sockaddr_in sa; socklen_t sl; ... getsockname(sockfd, (struct sockaddr*)&sa, &sl); ... ,所以你有效地传递了一些垃圾指针值。它必须是:

{{1}}

答案 3 :(得分:1)

只是要添加,valgrind在检测未初始化的指针或任何指针相关的错误方面非常有用。