c - 从外部函数返回字符串,同时防止内存泄漏

标签 c pointers

我试图通过 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;
}

现在事情是这样的:

  1. 如果我使用 strdup 将“hostname”复制到“visname”,那么我很确定我需要以某种方式释放 visname,但是由于我通过 return 传递它,所以我的问题是是否在返回后释放它(在“fun”内) “函数)可以吗?
  2. 如果我在“fun”中打印“hostname”或“visname”然后传递它 - 这似乎也有效,尽管我的假设是这可能是由于“未定义的行为”?
  3. 由于 char *visname 是指向局部变量“hostname”的指针,因此不应该简单地使用: char *visname = hostname 工作(即返回主机名字符串)?

编辑

我很确定我可以将一个字符串作为参数传递给 fun 函数,然后返回它,但由于它的长度是可变的,这意味着我每次都需要释放它。

所以我的偏好是通过函数传递主机名,然后我将在 main 中处理它...

最佳答案

  1. 不,您需要在函数外释放它。

  2. 如果您已经为其分配了内存(并且那里有一个有效的字符串),则可以对其进行 printf,因为 printf 不会更改其参数。

  3. 否,因为局部变量将在函数退出时失效,并且您将返回指向不存在(在非此函数范围内)对象的指针。

    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/

相关文章:

c++ - 无法更新作为列表中节点一部分的对象内的值

c - 如何知道文件在linux中被修改

c - 指针和结构问题

c - 是否可以仅使用指向结构的指针(无数据类型)来实现堆栈?

c++ - 超出范围时是否删除了指向堆栈对象的指针?

c - 来自不兼容指针类型警告的初始化。找不到问题

c - 为什么数组指针打印不正确?

float和int之间的转换,字节表示?

c - 如何读取这种格式

c - 在C中用栈实现链表