如何从函数返回 char 数组?

Posted

技术标签:

【中文标题】如何从函数返回 char 数组?【英文标题】:How do I return a char array from a function? 【发布时间】:2011-08-05 08:31:36 【问题描述】:

我尝试了以下方法:

char[10] testfunc()

    char[10] str;

    return str;

【问题讨论】:

那么,您已经尝试了一件事,但没有成功,现在您要问了吗?你用过搜索功能吗?你有没有看过你提问时提出的建议?您是否查看过此页面右侧的相关列表?像这样的问题已经在 SO 上被问过无数次了,所以只需 最少 的努力,您应该能够找到解决方案。 这个问题已经被问过(和回答)很多次了。看看:how to return an array in a c method 参见:C FAQ Chapter 19: Returning arrays。 重新打开是因为alleged duplicate 不是,并且该问题的答案在这里不适用。 【参考方案1】:

当您在堆栈上创建的函数内部创建局部变量时,它们很可能在退出函数时在内存中被覆盖。

所以在大多数 C++ 实现中这样的代码将无法工作:

char[] populateChar()

    char* ch = "wonet return me";
    return ch;

解决方法是创建要在函数外部或要使用它的位置填充的变量,然后将其作为参数传递并操作函数,例如:

void populateChar(char* ch)
    strcpy(ch, "fill me, Will. This will stay", size); // This will work as long as it won't overflow it.


int main()
    char ch[100]; // Reserve memory on the stack outside the function
    populateChar(ch); // Populate the array

使用 std::move(ch) 将左值转换为右值的C++11 解决方案:

void populateChar(char* && fillme)
    fillme = new char[20];
    strcpy(fillme, "this worked for me");


int main()
    char* ch;
    populateChar(std::move(ch));
    return 0;

或者 C++11 中的这个选项:

char* populateChar()
    char* ch = "test char";
    // Will change from lvalue to r value
    return std::move(ch);


int main()
    char* ch = populateChar();
    return 0;

【讨论】:

【参考方案2】:

您必须意识到char[10] 类似于char*(请参阅@DarkDust 的评论)。您实际上是在返回一个指针。现在指针指向一个变量(str),一旦你退出函数,它就会被销毁,所以指针指向......什么都没有!

通常在C语言中,这种情况下你显式分配内存,函数结束时不会被销毁:

char* testfunc()

    char* str = malloc(10 * sizeof(char));
    return str;

请注意! str 指向的内存现在永远不会被破坏。如果你不注意这一点,你就会得到所谓的“内存泄漏”。完成后一定要free()内存:

foo = testfunc();
// Do something with your foo
free(foo); 

【讨论】:

char 数组与 char 指针不同。请参阅C FAQ question 6.2。 公平地说,Marjin 说“相似”。来自链接的常见问题解答“数组不是指针,尽管它们密切相关(参见问题 6.3)并且可以类似地使用。”这基本上就是 Marjin 所说的。【参考方案3】:

char*返回一个char数组,但是你写的函数不起作用,因为你返回的是一个自动变量,当函数退出时会消失。

使用这样的东西:

char *testfunc() 
    char* arr = malloc(100);
    strcpy(arr,"xxxx");
    return arr;

这当然是如果您要返回 C 意义上的数组,而不是 std:: 或 boost:: 或其他东西。

如评论部分所述:记得释放调用者的内存。

【讨论】:

对不起,Felice,但你没有理解我的意思;内存泄漏不在分配中(并且 strcpy 也根本没有帮助)。这是您通过 malloc 保留内存,但没有人释放该内存(在这种情况下调用 free())。您应该注意,在这种情况下,调用者函数应该检查指针是否不为空,然后在使用后对其进行 free()。否则,您将引入内存泄漏。无论如何,这是一种不好的做法,应该像地狱一样避免。 @mydaemon 好吧,我无法编写整个程序的所有代码,很明显OP必须在使用后释放内存。正如您所指出的,编辑之前的代码是错误的,因为它会导致分配的指针丢失。 我同意这个改变,但作为一个建议,永远不要假设 op 会比你知道同样的事情。添加注释实际上需要 30 秒:您应该从调用者函数中免费调用”。 如here 所说,您需要将malloc() 的返回值进行转换。【参考方案4】:

与Boost:

boost::array<char, 10> testfunc()

    boost::array<char, 10> str;

    return str;

无法从函数返回普通的char[10](或任何其他数组)。

【讨论】:

这会在退出时进行复制,而不是传递引用。可能不是问题,但对于大型阵列,这可能是一笔可观的成本。但是,使用返回值优化 (en.wikipedia.org/wiki/Return_value_optimization) 您可以完全省略副本。 除了boost::array,也可以使用std::array,避免对boost的依赖。【参考方案5】:

最好作为输出参数:

void testfunc(char* outStr)
  char str[10];
  for(int i=0; i < 10; ++i)
    outStr[i] = str[i];
  

调用

int main()
  char myStr[10];
  testfunc(myStr);
  // myStr is now filled

【讨论】:

请同时传递容量作为参数,这样太脆弱了。 另外,strncpymemcpy 在复制结果时效率更高。【参考方案6】:

当您使用 C++ 时,您可以使用 std::string

【讨论】:

当你回答这个问题时,你可以留在话题上。用户问如何从一个函数返回一个char数组,而不是他/她应该使用什么reasoning 究竟为什么 char 数组是未知的。这可能是一种练习,可能是一项家庭作业,可能是在幕后研究……最好不要假设。

以上是关于如何从函数返回 char 数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何将转换为 char 数组的 int 返回到 main 以显示它

如何从string类型的变量 返回一个char* 类型

如何返回一个 char 数组并在 main 中打印它?

如何从函数中返回字符串

从函数返回 char[]/string [重复]

如何从 char* 函数返回指针