在C ++中返回一组向量

时间:2013-02-23 20:03:13

标签: c++ arrays pointers vector

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

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 个答案:

答案 0 :(得分:4)

您正在返回指向仅存在于函数范围内的内容的指针。函数完成后,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范围的循环语法):

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;
}

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

如果您的编译器不支持std::array,请尝试std::tr1::arrayboost::array

答案 1 :(得分: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;
}

答案 2 :(得分: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;
}

答案 3 :(得分:0)

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

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