C++ – returning an array of vectors in C++

arrayscpointersvector

I'm having difficulty returning an array of string vectors. I have a function:

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

and later I use the function like

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

but I keep getting segmentation fault. I realize I must be using pointers improperly, but how might I fix this? I use the array of vectors because it is very easy to refer to it by index (I only need three, non dynamic). Thanks!

Best Answer

You are returning a pointer to something that only lives in the scope of the function. Once the function is done, cVec vanishes and the caller is left with a dangling pointer. I suggest returning an object that can actually be copied, such as an 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;
}

I have commented out strvec here because it seems to play no role in the function.

You can then use it like this (C++11 range based for loop syntax):

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

Note that the push_backs may not be necessary if your compiler supports C++11 initializer list initialization.

If your compiler doesn't support std::array, try std::tr1::array from , or boost::array.