在C++函数中返回字符串数组

27

我是C++的新手。为了学校项目,我需要编写一个函数,使其能够返回字符串数组。

目前,在我的头文件中有以下内容:

Config.h

string[] getVehicles(void);

Config.cpp

string[] Config::getVehicles(){
string test[5];
test[0] = "test0";
test[1] = "test1";
test[2] = "test2";
test[3] = "test3";
test[4] = "test4";

return test;}

很明显这样做是行不通的,但这就是我试图做的事情的想法。 在Java中,这将是实现它的方式。我已经尝试通过谷歌搜索我的问题,但说实话没有找到任何清晰的答案。


当你在这里的时候,也可以看看向量。使用起来更容易。因为现在调用getVehicles的人不知道数组的长度。 - RvdK
使用std::vector - 今天我第一次打这个。真的需要一组标准简单答案的网页。使用std::vector,不要返回本地变量的地址等。 - pm100
3个回答

31

也许在这种情况下使用向量会更好,但这不是问题的正确答案。它不能工作的原因是变量test只存在于函数的作用域中。因此,您必须自己管理内存。以下是一个示例:

string* getNames() {
 string* names = new string[3];
 names[0] = "Simon";
 names[1] = "Peter";
 names[2] = "Dave"; 

 return names;
}
在这种情况下,你返回一个指向堆中位置的指针。堆内存中的所有内存都必须手动释放。因此,如果你不再需要该内存,现在就是你删除内存的工作:
delete[] names;

2
现在,我该如何找到返回数组的长度? - thefourtheye
谢谢,这解决了我的问题!我试图解决这个问题已经好几个小时了,而我的问题是我将字符串* names声明为静态的而不是动态的。 - mp19uy
1
如果问题是关于如何实现与Java相同的功能,那么这也不是一个答案。这段代码没有提供Java提供的垃圾回收机制,字符串也不是Unicode等等。在C++中返回动态分配的字符串数组永远不是正确的做法(除非你有一个经过验证的特定情况)。如果你想用Java就用Java……如果你想用C++就用C++。在C++中编写Java代码是一个非常可疑的(如果不是愚蠢的)方法。 - 6502
1
在C++和C中,常见的做法是将返回的数组长度作为单独的数字返回(使用size_t,因为这是标准无符号整数类型)。因此,在参数中使用引用size_tsize_t&length),因为返回值已经是数组。 - Light Drake
使用 std::vector<std::string> - 你会更加开心。 - pm100

19

在C++中,你不使用数组,而是使用std::vector实例。在C++中,数组必须具有编译时固定的长度,而std::vector实例可以在运行时更改其长度。

std::vector<std::string> Config::getVehicles()
{
    std::vector<std::string> test(5);
    test[0] = "test0";
    test[1] = "test1";
    test[2] = "test2";
    test[3] = "test3";
    test[4] = "test4";
    return test;
}

std::vector 还可以动态增长,因此在 C++ 程序中,您会更经常地发现类似以下的用法:

std::vector<std::string> Config::getVehicles()
{
    std::vector<std::string> test; // Empty on creation
    test.push_back("test0"); // Adds an element
    test.push_back("test1");
    test.push_back("test2");
    test.push_back("test3");
    test.push_back("test4");
    return test;
}

在C++中动态分配一个std::string数组从技术上讲是可能的,但这是一个糟糕的想法(例如C++没有像Java那样提供垃圾回收器)。

如果你想在C++中编程,那么先找一本好的C++书籍并逐页阅读它... 在C++中编写Java代码是灾难的开始,因为尽管两者表面上有花括号的相似之处,但在很多根本的方面它们是非常不同的语言。


0

试试这个

#include <iostream>
#include <string>

using namespace std;

string * essai()
    {
    string * test = new string[6];
    test[0] = "test0";
    test[1] = "test1";
    test[2] = "test2";
    test[3] = "test3";
    test[4] = "test4";
    cout<<"test et *test\t"<<&test<<' '<<*(&test)<<'\n';
    return test;
    }

main()
    {
    string * toto;
    cout<<"toto et *toto\t"<<&toto<<' '<<*(&toto)<<'\n';
    toto = essai();
    cout<<"**toto\t"<<*(*(&toto))<<'\n';
    cout<<"toto\t"<<&toto<<' '<<*(&toto)<<'\n';
    for(int i=0; i<6 ; i++)
        {
        cout<<toto[i]<<' '<<&toto[i]<<'\n';
        }
    }

例如,在我的电脑上,结果是:
toto et *toto   0x7ffe3a3a31b0 0x55dec837ae20
test et *test   0x7ffe3a3a3178 0x55dec9ddd038
**toto  test0
toto    0x7ffe3a3a31b0 0x55dec9ddd038
test0 0x55dec9ddd038
test1 0x55dec9ddd058
test2 0x55dec9ddd078
test3 0x55dec9ddd098
test4 0x55dec9ddd0b8
 0x55dec9ddd0d8

获取地址和地址内容可以帮助您理解c++中的数组是多么基础:它不提供任何方法,您可以在没有分配内存的情况下访问索引(循环中的值6)。 你的第一个例子展示了局部数组(test)的直接分配,因此无法返回它(局部数组会消失),在这个例子中,局部变量也会消失,但总有一个变量访问到已分配内存的这一部分,即函数,然后是接收函数结果的变量,所以调用函数后变量test就消失了,但内存仍然被分配。敬礼。


分配内存后不要忘记释放它!每个带有“new”的行都应该有一行与之匹配的“delete”。 - Pillager225

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接