1

我很难返回一个字符串向量数组。我有一个功能:

std::vector<std::string>* generatecVec(std::vector<std::string> strVec){
  std::vector<std::string> cVec[3];
  cVec[0].push_back("Test11");
  cVec[0].push_back("Test12");
  cVec[0].push_back("Test13");
  cVec[1].push_back("Test21");
  cVec[1].push_back("Test22");
  cVec[1].push_back("Test23");
  cVec[2].push_back("Test31");
  cVec[2].push_back("Test32");
  cVec[2].push_back("Test33");
  return cVec;
}

后来我使用了类似的功能

std::vector<std::string> *cVec = generatecVec(strVec);
for(std::vector<string>::iterator it = cVec[0].begin(); it != cVec[0].end(); ++it) {
    std::cout << *it;
}

但我不断收到分段错误。我意识到我必须不正确地使用指针,但我该如何解决这个问题?我使用向量数组是因为它很容易通过索引来引用它(我只需要三个,非动态的)。谢谢!

4

4 回答 4

5

您正在返回一个指向仅存在于函数范围内的东西的指针。一旦函数完成,就会cVec消失,调用者会留下一个悬空指针。我建议返回一个可以实际复制的对象,例如std::array<std::vector<std::string> 3>.

#include <array> // for std::array

std::array<std::vector<std::string>,3> generatecVec(/*std::vector<std::string> strVec*/){
  std::array<std::vector<std::string>,3> cVec;
  cVec[0].push_back("Test11");
  cVec[0].push_back("Test12");
  cVec[0].push_back("Test13");
  cVec[1].push_back("Test21");
  cVec[1].push_back("Test22");
  cVec[1].push_back("Test23");
  cVec[2].push_back("Test31");
  cVec[2].push_back("Test32");
  cVec[2].push_back("Test33");
  return cVec;
}

我在这里注释掉了strvec,因为它似乎在函数中没有任何作用。

然后您可以像这样使用它(基于 C++11 范围的 for 循环语法):

auto cVec = generatecVec(); // no strVec because it doesn't play any role
for(auto it = cVec[0].cbegin(); it != cVec[0].cend(); ++it) {
    std::cout << *it;
}

请注意,push_backs如果您的编译器支持 C++11 初始化程序列表初始化,则可能不需要。

如果您的编译器不支持std::array,请尝试std::tr1::arrayfrom 或boost::array.

于 2013-02-23T20:05:25.410 回答
0

奇怪的是,当您需要收集字符串时使用字符串向量,而当您需要收集向量时使用指针。使用 typedef 应该有助于抽象细节并查看可能的解决方案:

typedef std::vector<std::string> strings;
typedef std::vector<strings> strings_seq;

strings_seq generateVec()
{
  strings_seq cVec( 3 );
  cVec[0].push_back("Test11");
  cVec[0].push_back("Test12");
  cVec[0].push_back("Test13");
  cVec[1].push_back("Test21");
  cVec[1].push_back("Test22");
  cVec[1].push_back("Test23");
  cVec[2].push_back("Test31");
  cVec[2].push_back("Test32");
  cVec[2].push_back("Test33");
  return cVec;
}
于 2013-02-23T20:17:15.883 回答
0

正如其他人已经解释的那样,您正在返回一个本地引用,即函数范围之外的垃圾。根据经验,我尽量避免使用原始指针,因为最终我忘记在使用后删除指针,或者初始化一个指针以开始。

当您返回 std::array 或 std::vector 时,您调用复制构造函数并接收向量、数组等的新副本......我个人倾向于在这些情况下使用 boost shared_ptr,因为它们克服了大多数缺点带有经典的 C 指针

于 2013-02-23T20:17:27.447 回答
0

您正在返回一个指向自动数组的指针,该数组在超出范围时被破坏,并且您的指针指向一个充满破坏向量的破坏数组。

使用std::array并按值返回:

// This means: std::array of 3 std::vector<string>
//   Type--VVVVVVVVVVVVVVVVVVVVVVVV  V-- Array size
std::array<std::vector<std::string>, 3> generatecVec(std::vector<std::string> strVec){
  return { {
     { "Test11", "Test12", "Test13" },
     { "Test21", "Test22", "Test23" },
     { "Test31", "Test32", "Test33" }
  } };
}

auto cVec = generatecVec(strVec);
for(auto it = cVec[0].begin(); it != cVec[0].end(); ++it) {
    std::cout << *it;
}
于 2013-02-23T20:07:21.953 回答