从函数返回char指针数组(c ++)

时间:2013-07-20 01:04:02

标签: c++ arrays pointers char

我正在尝试返回char数组的数组。虽然我能够成功创建数组,但我显然错误地返回了它。

我的语法是关闭还是我提出了一些我忽略的错误?

以下是最相关的行,完整的功能如下

// prototype
  char * testFunc();

// Function
    char * testFunc() {
      char* ptrArray[2];   
      return(*ptrArray);
    }
// Assignment in main()
    int main {
      char * res = testFunc();
    }

以下是完整代码的简化版

#include <iostream>
using std::cout;

// prototype
char * testFunc();

int main() {

    short i, j;
    char * res = testFunc();

        for (i=0; i < 2; i++)
           cout <<"This is  res[" << i << "] : " << res[i] <<"\n";


    return(0);
}

char * testFunc() {

    char word1[] = "one";
    char word2[] = "two";

    // create an array of char*
    char* ptrArray[2];

    ptrArray[0] = word1;
    ptrArray[1] = word2;

    for (int i=0; i<2; i++)
        cout <<"This is ptrArray[" << i << "] : " << ptrArray[i] <<"\n";

    return(*ptrArray);
}

2 个答案:

答案 0 :(得分:4)

从函数返回在自动存储中分配的对象(也称为“堆栈对象”)是未定义的行为。当您需要在C中返回数组时,您有三个选项:

  1. 返回在静态存储区域中分配的对象
  2. 返回动态存储区域中分配的对象,或
  3. 获取缓冲区和最大大小,并返回数组的实际大小。
  4. 第一个选项很少适用,因为它使您的函数不可重入。第三种选择很普遍,但它有一些限制:当你必须返回更多的数据而不是适合缓冲区时,需要多次调用API。

    这给我们留下了第二个选项:使用new分配您要返回的内存,将数据复制到其中,然后将结果返回给调用者。现在调用者有责任释放动态内存:

    // You need two asterisks: a string needs one asterisk, you return
    // a 1-D array of strings, so you need another level of indirection.
    char ** testFunc() {
        char word1[] = "one"; // Automatic memory - needs a copy
        char word2[] = "two"; // Automatic memory - needs a copy
    
        // create an array of char*
        char** ptrArray = new char*[2];
    
        ptrArray[0] = new char[strlen(word1)+1]; // Plus one for the null terminator
        strcpy(ptrArray[0], word1);
        ptrArray[1] = new char[strlen(word2)+1]; // Plus one for the null terminator
        strcpy(ptrArray[1], word2);
        for (int i=0; i<2; i++)
            cout <<"This is ptrArray[" << i << "] : " << ptrArray[i] <<"\n";
    
        return ptrArray;
    }
    

    注意:您可能尚未访问标准库,因此下面的解决方案可能不适用。但是,你应该知道上面的解决方案最好的C ++可以做到:你可以重写这个机智动态容器,并使代码更容易阅读:

    vector<strig> testFunc() {
        vector<string> res;
        res.push_back("one");
        res.push_back("two");
        return res;
    }
    

    在C ++ 11中,你可以做得更好:

    vector<string> test() {
        return vector<string> {"one", "two"};
    }
    

答案 1 :(得分:1)

单个“字符数组”大致相当于char *。要返回数组数组,您需要char **char[]*

正如另一个答案所说,如果你从函数内部返回指针,那么这些指针需要是“全局”内存 - 而不是只在函数内有效的局部变量。函数返回后,返回指向“基于堆栈”的局部变量的指针不再有效,因为下一个函数调用(或更早)将覆盖该堆栈空间。

[自原始发布以来,有人建议{const const char*和(推测)const char**首选“const correctness”。

我的C ++生锈了......但是:

const char** testFunc() {
    const char word1[] = "one";
    const char word2[] = "two";

    // create an array of char*
    const char** ptrArray = (const char **) malloc( 2 * sizeof(char *));
    ptrArray[0] = word1;
    ptrArray[1] = word2;

    for (int i=0; i<2; i++)
        cout <<"This is ptrArray[" << i << "] : " << ptrArray[i] <<"\n";

    return ptrArray;
}

主要是:

int main() {
    short i;

    // get the array -- will now be our responsibility to free
    const char** ptrArray = testFunc();

    for (i=0; i < 2; i++) {
        // read single pointer (char*),  from our array of pointers (char**)
        const char* word = ptrArray[i];
        cout <<"This is  res[" << i << "] : " << word <<"\n";
    }

    // free it.
    free( ptrArray);

    return(0);
}

在提出原始问题时,数组的输入是字符串常量。因此,返回可变数组的常量字符串是首选,以返回可变字符串的可变数组。

即使整个系统(问题中没有显示)以编程方式构建字符串,但根据其他答案,很可能最好返回作为const char * - 不作为进一步修改的缓冲区。