1

我正在尝试返回一个数组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);
}
4

2 回答 2

4

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

  1. 返回分配在静态存储区的对象,
  2. 返回分配在动态存储区中的对象,或
  3. 获取缓冲区和最大大小,并返回数组的实际大小。

第一个选项很少适用,因为它使您的函数不可重入。第三种选择很普遍,但也有局限性:当您必须返回超出缓冲区容量的数据时,需要多次调用 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"};
}
于 2013-07-20T01:08:13.227 回答
1

单个“字符数组”大致相当于char *. 要返回一个数组数组,您需要char **或者也许char[]*.

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

[自最初发布以来,有人建议const char*和(大概)const char**将是首选,因为“常量正确性”]。

我的 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 *- 不被视为进一步修改的缓冲区。

于 2013-07-20T01:24:33.743 回答