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

しかし、私はセグメンテーション違反を起こし続けています。ポインタを不適切に使用している必要があることはわかっていますが、これを修正するにはどうすればよいですか?ベクトルの配列を使用するのは、インデックスで参照するのが非常に簡単だからです(必要なのは、動的ではない3つだけです)。ありがとう!

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機能に何の役割も果たさないようですので、ここでコメントしました。

次に、次のように使用できます(forループ構文に基づく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;
}

push_backsコンパイラがC++11初期化子リストの初期化をサポートしている場合は、が必要ない場合があることに注意してください。

コンパイラがをサポートしていない場合は、、、またはからstd::array試してください。std::tr1::arrayboost::array

于 2013-02-23T20:05:25.410 に答える
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 に答える
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を返すときは、コピーコンストラクターを呼び出して、vector、arrayなどの新しいコピーを受け取ります...これらの状況では、boost shared_ptrを使用する傾向があります。これは、クラシックCポインターが付属しています

于 2013-02-23T20:17:27.447 に答える