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

我尝试了以下方法:

char[10] testfunc()
{
    char[10] str;

    return str;
}

【问题讨论】:

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

标签: c++ arrays function return


【解决方案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 数组是未知的。这可能是一种练习,可能是一项家庭作业,可能是在幕后研究……最好不要假设。
    猜你喜欢
    • 1970-01-01
    • 2020-02-21
    • 2018-05-09
    • 1970-01-01
    • 1970-01-01
    • 2018-01-10
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多