2012-02-12 13 views
1

2つの3D配列の要素を追加し、その結果を3番目の3D配列に格納し、結果を1次元ベクトルにコピーして返します一定の基準によって。私が抱えている問題は、ローカル変数を返すことができないため、動的メモリ割り当てを使ってベクトルを返す方法です。これは、ローカル変数を返すことができれば、コードは次のようになります。ここではC++でのベクトルの動的メモリ割り当て

template <class T> 
const vector<T>& allOperations(T*** const &x, T*** const &y, T*** &z, int height, int width, int depth) 
{ 
    vector<T> results(height*width*depth); 

    // Add the values of array x and y 
    for (int i = 0; i < height; i++) 
    { 
     for (int j = 0; j < width; j++) 
     { 
      for (int k = 0; k < depth; k++) 
      { 
       z[i][j][k] = x[i][j][k] + y[i][j][k]; 
      } 
     } 
    } 

    int l = 0; 
    //Places the values of array z into a vector 
    for (int i = 0; i < height; i++) 
    { 
     for (int j = 0; j < width; j++) 
     { 
      for (int k = 0; k < depth; k++) 
      { 
       results[l] = z[i][j][k]; 
       l++; 
      } 
     } 
    } 
    return results; 
} 

は、動的なメモリ割り当てを使用しての私の間違った試みです:

template <class T> 
const vector<T>& allOperations(T*** const &x, T*** const &y, T*** &z, int height, int width, int depth) 
{ 
    vector<T>* results(height*width*depth) = new vector<T>; 

    // Add the values of array x and y 
    for (int i = 0; i < height; i++) 
    { 
     for (int j = 0; j < width; j++) 
     { 
      for (int k = 0; k < depth; k++) 
      { 
       z[i][j][k] = x[i][j][k] + y[i][j][k]; 
      } 
     } 
    } 

    int l = 0; 
    //Places the values of array z into a vector 
    for (int i = 0; i < height; i++) 
    { 
     for (int j = 0; j < width; j++) 
     { 
      for (int k = 0; k < depth; k++) 
      { 
       *results[l] = z[i][j][k]; 
       l++; 
      } 
     } 
    } 
    return *results; 
} 
+0

あなたは、単にメモリのオーバーヘッドなし 'ベクトル'を返すことができますので、すべてのSTLコンテナのコンテンツは、自動的に、ヒープ上に格納されています。 'const' shoulsも動作します。まだそれを試していない。私はあなたには、2つの理由からSTLコンテナを動的メモリ割り当てと組み合わせて使用​​すべきではないと言われました。まず、コードは信じられないほど乱雑になります。多次元配列の場合2番目:スタック上にあるコンテナがローカル関数スタックに参照を格納するだけなので、ちょっとした作業です。それ以外のものはすべてヒープ上に作成されます。 – guitarflow

+0

これは万一の宿題ですか?そうであれば、新しく作成されたベクトルが定数参照によって返されるという奇妙な要件が説明されます。 –

答えて

2

それはへの参照を戻すことは意味がありませんローカル変数。 2番目の解決策(newのベクトルへの参照を返す)に頼るなら、ほぼ確実にメモリリークが発生します。慣例により、参照を取得することは、通常、他のエンティティがすでに返されたオブジェクトのライフタイムを管理していることを意味します。

この問題を回避するには、複数のことがあります。


動的メモリ割り当てを実行しないで、関数の署名を変更します。

// Return a copy of the vector. 
vector<T> allOperations(T*** const &x, T*** const &y, T*** &z, int height, int width, int depth) 
{ 
    vector<T> results(height*width*depth); 
    // ... 
    return results; 
} 

あなたはコンパイラがcopy elisionを行い、および/またはC++11 move constructorsをサポートしている場合は、「コピーは」場所を取ることはありませんし、リターンは非常に効率的になります。その場合

// Return a pointer to a newly allocated vector. 
const vector<T>* allOperations(T*** const &x, T*** const &y, T*** &z, int height, int width, int depth) 
{ 
    vector<T>* results(height*width*depth) = new vector<T>; 
    // ... 
    return results; 
} 

は、smart pointerを返す代わりに戻って考えてみましょう。あなたが本当に動的に他のいくつかの制約を満たすためにベクトルを割り当てたい場合は


は、あなたはまた、関数のシグネチャを変更する必要があります裸のポインタ。


これがメンバー関数であれば、オブジェクト内にベクターを格納することができます。

template<typename T> 
class SomeClass 
{ 
    std::vector<T> results; 
public: 
    // ... 

    // Modify member and return reference to internal member. 
    const vector<T>& allOperations(T*** const &x, T*** const &y, T*** &z, int height, int width, int depth) 
    { 
     results.resize(height*width*depth); 
     // ... 
     return results; 
    } 
}; 

別の可能性のある、しかしは強くソリューションは、いくつかのグローバル変数への参照を返すことです落胆しました。

std::vector<T> results; 

// Modify global and return reference to global variable. 
const vector<T>& allOperations(T*** const &x, T*** const &y, T*** &z, int height, int width, int depth) 
{ 
    results.resize(height*width*depth); 
    // ... 
    return results; 
} 

あるいは、その(しかし正確に相当)を装った形で:

// Modify global and return reference to global variable. 
const vector<T>& allOperations(T*** const &x, T*** const &y, T*** &z, int height, int width, int depth) 
{ 
    // Global variable with name not visible outside the function. 
    static std::vector<T> results; 

    results.resize(height*width*depth); 
    // ... 
    return results; 
} 
+0

この関数は、変数だけでなく、定数参照を返す必要があります。そのため、私はベクトルを動的に割り当てる必要があります。 2番目の例は、新しく割り当てられたベクトルへのポインタを返しますが、新しく割り当てられたベクトルへの参照を返す場合、コードはどのように見えるでしょうか? – user1205613

+0

@ user1205613:あなたは、関数内で動的に割り当てられたベクトルがある点として関数の外側で削除されなければならないことを認識しています。そうしないとメモリリークが発生します。 –

+0

@ user1205613:あなたは構文的には 'new'のベクトルへの定数参照を返すことができますが、呼び出し元がメモリを"所有しない "ため、*決して*行うべきではありません。あなたの 'allOperations()'関数が実際にオブジェクトメソッドである場合、そのオブジェクトにベクトルを所有させることができますが、そうではありません。お客様の要件は、記載されているように、不明確です。関数が既存のオブジェクトへの参照を返すようにし、同じ関数でオブジェクトを作成したいとします。それは意味をなさない。 –

0

代わりに新しいmalloc関数/を使用しての文字列のベクトルを使用してください。

int t; std::cin >> t; 
std::vector<std::string> strings(t); //Create t strings 
for(int i = 0; i < t; i++) 
std::cin >> strings[i]; //Read into each string 
関連する問題