段错误(可能是由于转换)

发布于 2024-09-05 12:54:27 字数 1573 浏览 7 评论 0原文

我通常不会去 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无所谓啦 2024-09-12 12:54:28

只是补充一下,valgrind 在检测未初始化的指针或任何与指针相关的错误方面非常有用。

just to add, valgrind is pretty useful in detecting uninitialized pointers or for that matter any pointer related errors.

悲欢浪云 2024-09-12 12:54:28

在将 sa 传递给 getsockname 之前,您没有分配它,因此您实际上在其中传递了一些垃圾指针值。它需要是:

struct sockaddr_in sa;
socklen_t sl;
...
getsockname(sockfd, (struct sockaddr*)&sa, &sl);
...

You did not allocate sa before passing it to getsockname, so you effectively passed in some garbage pointer value there. It needs to be:

struct sockaddr_in sa;
socklen_t sl;
...
getsockname(sockfd, (struct sockaddr*)&sa, &sl);
...
活泼老夫 2024-09-12 12:54:27

您似乎从未将指针 sa 初始化为指向有效的 sockaddr (或 sockaddr_in)对象。

如果您替换

sockaddr* sa;

sockaddr addr;

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

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

例如

socklen_t slen = sizeof addr;

,使用 &slen 而不是 sl

It doesn't look like you ever initialize the pointer sa to point at a valid sockaddr (or sockaddr_in) object.

If you replace

sockaddr* sa;

with

sockaddr addr;

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 the socklen_t* parameter needs to point at a valid socklen_t object initialized to the size in bytes of the address buffer.

E.g.

socklen_t slen = sizeof addr;

and use &slen instead of sl.

你的心境我的脸 2024-09-12 12:54:27

在我看来,您似乎从未将 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 :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文