【问题标题】:C String Return Function Returns GarbageC字符串返回函数返回垃圾
【发布时间】:2013-10-30 20:14:27
【问题描述】:

我在从函数返回字符串时遇到问题。它在 main 方法中打印出一个垃圾值。我在这个论坛上看到了一个类似的问题,但该页面上的结果对我没有帮助。我不想将另一个变量传递给函数。我希望能够按原样返回字符串值。我该怎么做呢?

char *LookupPath(char **argv, char **dir)
{
    /* String Name To Be Returned */
    char path_name[MAX_PATH_LEN] = {0};
    char *result = malloc(sizeof(path_name));
    int i;

    /* Check To See If File Name Is Already An Absolute Path Name */
    if(*argv[0] == '/') {

    }

    /* Look In Path Directories */
    for(i = 0; dir[i] != NULL; i++) {
        strncat(path_name, dir[i], sizeof(path_name));
        strncat(path_name, "/", sizeof(path_name));
        strncat(path_name, argv[0], sizeof(path_name));
        result = path_name;
        if(access(result, F_OK) == 0) {
            printf("result: %s\n", result);
            return result;
        }
        path_name[0] = '\0';
    }

    /* File Name Not Found In Any Path Variable */
    return NULL;
}

非常感谢您的帮助!

【问题讨论】:

  • 您没有正确使用strncat。最后一个参数应该是要追加的最大字符数,而不是字符串应该是的最大字符数。考虑使用snprintf"%s/%s" 格式等。
  • 你真的应该学习如何使用gdb调试器。

标签: c string function return


【解决方案1】:

您分配的值path_name 超出了它实际可以容纳的数量。

    strncat(path_name, dir[i], sizeof(path_name));
    strncat(path_name, "/", sizeof(path_name));
    strncat(path_name, argv[0], sizeof(path_name));

应该是:

    sprintf(path_name, "%s%s%s", dir[i],"/",argv[0]);

【讨论】:

  • 不是%S,而是%s,格式控制字符串中没有空格。
  • @BasileStarynkevitch:谢谢您,先生,请注意
  • 如果你知道缓冲区的大小,如果函数可用,你应该改用snprintf,这样更难溢出缓冲区。
  • 谢谢!我最终使用了这个。
  • @JakeZ:对你有好处。而且,这与您使用的东西无关。据说“在 C 中,总是有更好的方法来完成它!”。关键是,您必须了解使用什么、在哪里使用以及为什么要这样做..
【解决方案2】:

你不能从一个函数返回一个本地数组(比如你的path_name)。该本地数组位于call frame 内,返回时会弹出。

正如其他人回答的那样,你应该这样做

strncpy(result, path_name, MAX_PATH_LEN);

document 调用者应该释放结果的约定。

顺便说一句,您的代码效率很低;您正在为通常更小的字符串分配相当大的 MAX_PATH_LEN(通常为 4096)块。

如果使用 GNU 扩展,您可以简单地使用 asprintf(3)(参见 this)或至少删除您的 mallocreturn strdup(path_name); 并使用 strdup(3)(这是标准的,不需要任何 GNU 扩展)。

并学习如何使用valgrind

【讨论】:

  • 另外,他泄露了result(即最初分配给的内容)。
【解决方案3】:
result = path_name;

应该是:

strcpy(result, path_name);

或者更好,去掉path_name,直接使用result

请注意,您应该记住在不使用时释放result,返回时,在调用它的函数中释放它。既然你返回NULL失败,那么直接释放它,不然就是内存泄漏了。

而你使用strncat 错误,请阅读manual

【讨论】:

    【解决方案4】:

    因为这条线:

    result = path_name;
    

    这个重新分配 result 指向局部变量path_name,当函数返回时,它超出了范围。这也意味着您有内存泄漏。

    不要使用临时的path_name 变量,而是直接写入result

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-08
      • 1970-01-01
      • 2013-02-07
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      相关资源
      最近更新 更多