我试图通过 getaddrinfo 函数传递一个可变长度的字符串,我的代码基本上是:
char *fun(char *ip) {
struct addrinfo* res;
int error;
// resolve the domain name into a list of addresses
error = getaddrinfo(ip, NULL, NULL, &res);
if (error != 0) {
if (error == EAI_SYSTEM) {
perror("getaddrinfo");
} else {
fprintf(stderr, "error in getaddrinfo: %s\n", gai_strerror(error));
}
exit(EXIT_FAILURE);
}
// go over returned result and do inverse lookup
char hostname[NI_MAXHOST];
error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, NI_MAXHOST, NULL, 0, 0);
if (error != 0) {
fprintf(stderr, "error in getnameinfo: %s\n", gai_strerror(error));
}
// here I use a pointer in order to pass the string without gcc complain about passing a local var
char *visname = strdup(hostname);
/* if I uncomment the below then string is passed correctly */
// printf("%s\n", hostname);
freeaddrinfo(res);
return visname;
}
int main() {
...
for (int n=0; n<ips; n++) {
printf("%s\n", fun(ip[n]) );
}
return 0;
}
现在事情是这样的:
- 如果我使用 strdup 将“hostname”复制到“visname”,那么我很确定我需要以某种方式释放 visname,但是由于我通过 return 传递它,所以我的问题是是否在返回后释放它(在“fun”内) “函数)可以吗?
- 如果我在“fun”中打印“hostname”或“visname”然后传递它 - 这似乎也有效,尽管我的假设是这可能是由于“未定义的行为”?
- 由于 char *visname 是指向局部变量“hostname”的指针,因此不应该简单地使用: char *visname = hostname 工作(即返回主机名字符串)?
编辑
我很确定我可以将一个字符串作为参数传递给 fun 函数,然后返回它,但由于它的长度是可变的,这意味着我每次都需要释放它。
所以我的偏好是通过函数传递主机名,然后我将在 main 中处理它...
最佳答案
不,您需要在函数外释放它。
如果您已经为其分配了内存(并且那里有一个有效的字符串),则可以对其进行 printf,因为 printf 不会更改其参数。
否,因为局部变量将在函数退出时失效,并且您将返回指向不存在(在非此函数范围内)对象的指针。
int main() { ... char *ptr; for (int n=0; n<ips; n++) { printf("%s\n", (ptr = fun(ip[n])) ); free(ptr); } return 0; }
编辑后;
int main() {
...
char ptr[MAXHOSTNAMESIZE +1];
for (int n=0; n<ips; n++) {
printf("%s\n", (fun(ip[n], ptr)) );
}
return 0;
}
或
int main() {
...
char *ptr = malloc(MAXHOSTNAMESIZE +1);
for (int n=0; n<ips; n++) {
printf("%s\n", (fun(ip[n], ptr)) );
}
free(ptr)
return 0;
}
char *fun(char *ip, char *buff) {
struct addrinfo* res;
int error;
///......
error = getnameinfo(res->ai_addr, res->ai_addrlen, buff, NI_MAXHOST, NULL, 0, 0);
if (error != 0) {
fprintf(stderr, "error in getnameinfo: %s\n", gai_strerror(error));
}
//....
return buff;
}
关于c - 从外部函数返回字符串,同时防止内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45588183/