getaddrinfo,分段错误
getaddrinfo, Segmentation Fault
我遇到以下代码的分段错误。
我需要程序做的是,当输入 invalid/unknown 名称或服务作为参数时,它仅针对该特定服务显示错误,并继续处理提供的其余服务.
现在,如果我在服务行中的任何位置包含无效服务(例如 ./dnslookup www.nhawurha.com www.google.com 或 www.google.com www.nhawurha.com),程序就可以运行
但是如果仅将无效服务用作唯一参数(例如 ./dnslookup www.nhawurha.com),它会在打印错误后给我一个分段错误
非常感谢任何形式的帮助,谢谢!
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#define BUFLEN 1500
int main(int argc, char *argv[]) {
struct addrinfo hints, *ai, *result;
char ipaddrv4[BUFLEN];
char ipaddrv6[BUFLEN];
int error;
if (argc < 2) {
fprintf(stderr, "Missing <hostname> after %s \n", argv[0]);
return 0;
}
for (int j = 1; j < argc; j++) {
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC; /* IPv4, IPv6, or anything */
hints.ai_socktype = SOCK_DGRAM; /* Dummy socket type */
error = getaddrinfo(argv[j], NULL, &hints, &result);
if (error) {
fprintf(stderr, "ERROR (%s: %s)\n", argv[j], gai_strerror(error));
continue;
}
for (ai = result; ai != NULL; ai = ai->ai_next) {
if (ai->ai_family == AF_INET) {
struct sockaddr_in *ipv4 = (struct sockaddr_in *) ai->ai_addr;
void *addr = &(ipv4->sin_addr);
inet_ntop(AF_INET, addr, ipaddrv4, BUFLEN);
printf("%s IPv4 %s\n", argv[j], ipaddrv4);
}
else if (ai->ai_family == AF_INET6) {
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *) ai->ai_addr;
void *addr = &(ipv6->sin6_addr);
inet_ntop(AF_INET6, addr, ipaddrv6, BUFLEN);
printf("%s IPv6 %s\n", argv[j], ipaddrv6);
}
else {
continue;
}
}
}
freeaddrinfo(result);
return 0;
}
查看 'result' 参数 - 如果您唯一的查找失败,结果将未初始化并且 freeaddrinfo
将出现段错误。首先尝试将其初始化为 NULL。
如果您有多个查找,则会出现第二个问题 - 内存泄漏,因为您没有对每个结果调用 freeaddrinfo
。
所以我觉得你的逻辑应该更像:
for each command line arg
if lookup succeeds
print result
free result
else
print error
参见 man page getaddrinfo
我遇到以下代码的分段错误。
我需要程序做的是,当输入 invalid/unknown 名称或服务作为参数时,它仅针对该特定服务显示错误,并继续处理提供的其余服务.
现在,如果我在服务行中的任何位置包含无效服务(例如 ./dnslookup www.nhawurha.com www.google.com 或 www.google.com www.nhawurha.com),程序就可以运行
但是如果仅将无效服务用作唯一参数(例如 ./dnslookup www.nhawurha.com),它会在打印错误后给我一个分段错误
非常感谢任何形式的帮助,谢谢!
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#define BUFLEN 1500
int main(int argc, char *argv[]) {
struct addrinfo hints, *ai, *result;
char ipaddrv4[BUFLEN];
char ipaddrv6[BUFLEN];
int error;
if (argc < 2) {
fprintf(stderr, "Missing <hostname> after %s \n", argv[0]);
return 0;
}
for (int j = 1; j < argc; j++) {
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC; /* IPv4, IPv6, or anything */
hints.ai_socktype = SOCK_DGRAM; /* Dummy socket type */
error = getaddrinfo(argv[j], NULL, &hints, &result);
if (error) {
fprintf(stderr, "ERROR (%s: %s)\n", argv[j], gai_strerror(error));
continue;
}
for (ai = result; ai != NULL; ai = ai->ai_next) {
if (ai->ai_family == AF_INET) {
struct sockaddr_in *ipv4 = (struct sockaddr_in *) ai->ai_addr;
void *addr = &(ipv4->sin_addr);
inet_ntop(AF_INET, addr, ipaddrv4, BUFLEN);
printf("%s IPv4 %s\n", argv[j], ipaddrv4);
}
else if (ai->ai_family == AF_INET6) {
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *) ai->ai_addr;
void *addr = &(ipv6->sin6_addr);
inet_ntop(AF_INET6, addr, ipaddrv6, BUFLEN);
printf("%s IPv6 %s\n", argv[j], ipaddrv6);
}
else {
continue;
}
}
}
freeaddrinfo(result);
return 0;
}
查看 'result' 参数 - 如果您唯一的查找失败,结果将未初始化并且 freeaddrinfo
将出现段错误。首先尝试将其初始化为 NULL。
如果您有多个查找,则会出现第二个问题 - 内存泄漏,因为您没有对每个结果调用 freeaddrinfo
。
所以我觉得你的逻辑应该更像:
for each command line arg
if lookup succeeds
print result
free result
else
print error
参见 man page getaddrinfo