1

ある関数から別の関数にマップを渡すときにメモリを適切に処理する方法。

作成したマップを返す関数があります。値オブジェクトはクラス foo です。foo を 3 つの異なる場所に出力すると、すべての場所で異なる値が得られます。初めて、正しい値が得られます。2番目と3番目はゴミです。

適切な場所に Foo オブジェクト ポインターを作成する必要があることはわかっています。

どこか知りたい?

std::map<int,Foo*> function_that_returns_the_map(){

  std::map<int,Foo*> myMap; 

  {

    int v = 0; 
    Foo *b = new Foo();

    // PRINTING FOO FIRST

    std::cout<<""<<*b<<endl;

    myMap.insert(std::pair<int,Foo*>(v,b))

  }

  // PRINTING FOO AGAIN 

  for(map<int,Foo*>::iterator it = myMap.begin();
  it != myMap.end(); ++it)
  {      
    std::cout << " " << *(it->second) << "\n";
  }


  return myMap;
  }

std::map<int, Foo*> myMap;
myMap = function_that_returns_the_map();

//PRINTING FOO AGAIN.

 std::map<int, Board*>::iterator it = myMap.begin();
 for (it=myMap.begin(); it!=myMap.end(); ++it)
   cout<<" "<<*(it->second)<<endl;  

私の実際のコードを見るにはここをクリックしてください。

更新: Foo のメンバー変数は、'new' 演算子を使用して割り当てられていませんでした。したがって、それらは範囲外になり、範囲外になるとガベージ値を持っていました。

4

3 に答える 3

1

あなたのコードにはかなりの数の小さなミスがありました (単なるタイプミスだと思います)。私はそれらを修正し、Fooクラスを提供しました。コンパイルして正常に実行され、3 つの場所すべてに正しい値が出力されます。

#include <iostream>
#include <map>

struct Foo
{
   Foo() : someValue(5) {};
   int someValue;
};

std::map<int,Foo*> function_that_returns_the_map()
{
   std::map<int,Foo*> myMap;
   {
      int v = 0; 
      Foo *b = new Foo();
      std::cout << (*b).someValue << std::endl; // PRINTING FOO FIRST
      myMap.insert(std::pair<int,Foo*>(v,b));
   }

   // PRINTING FOO AGAIN
   std::map<int, Foo*>::iterator it = myMap.begin();
   for(it; it != myMap.end(); ++it)
   { 
      std::cout << it->second->someValue << "\n";
   }
   return myMap;
}

int main()
{
   std::map<int, Foo*> myMap;
   myMap = function_that_returns_the_map();

   //PRINTING FOO AGAIN.

   std::map<int, Foo*>::iterator it = myMap.begin();
   for (it; it!=myMap.end(); ++it)
   std::cout << it->second->someValue << std::endl;
   return 0;
}

ここをクリックして出力を表示します。

したがって、問題は、質問で言及していないものにある必要があります。さらに支援するには、実際のコードを確認する必要があります。

于 2013-04-15T00:14:47.500 に答える
1

実際にstd::pair正しい値で を作成していることを確認してください。

myMap.insert(std::pair<int,Foo*>(v, b));
//                               ^^^^

または以下を利用しますstd::make_pair

myMap.insert(std::make_pair(v, b));
于 2013-04-14T23:30:07.570 に答える
0

「PRINTING FOO HERE」とコメントした場所で、どのようにコンパイルしていますか? 範囲外であるため、これらの場所のいずれかでローカル変数をFoo介して印刷することはできません。b代わりに、マップからオブジェクトを取得する必要があります

コードに次の変更を加えましたが、すべて正常に動作します。

class Foo
{
public:
    const int Value;
    Foo(int value) : Value(value) // add some kind of identifier to Foo so we can check it's not garbage
    { }
};

std::map<int,Foo*> function_that_returns_the_map()
{
    std::map<int,Foo*> myMap; 

    { // introducing a new scope

        int v = 0; 
        Foo *b = new Foo(98765);

        // PRINTING FOO HERE.
        std::cout << b->Value << std::endl;

        myMap.insert(std::pair<int,Foo*>(v,b));
    } // v, b go out of scope, are no longer accessible

    // PRINTING FOO HERE.
    std::cout << myMap[0]->Value << std::endl; // we can't use v, b anymore, so go fish in the map to find the Foo

    return myMap;
}

void main()
{
    std::map<int, Foo*> myMap;
    myMap = function_that_returns_the_map();

    //PRINTING FOO HERE.
    std::cout << myMap[0]->Value << std::endl; // we can't use v, b anymore, so go fish in the map to find the Foo
}

重要なのはスコーピングです。C++ の中括弧はスコープを意味します。そのスコープ内で宣言されたローカル変数は、スコープ外からは使用できません。うまくいけば、これはそれを説明するのに役立ちます. そうでない場合は、意味をなさないことについてコメントしてください。

PS:オブジェクトnewを作成するために使用したため、それらをクリーンアップするためにどこかを使用する必要があることを忘れないでください。そうしないと、プログラムでメモリリークが発生します。このため、通常、ポインターをマップやリストに直接配置することはありません。代わりに、オブジェクトのコピーを (ポインターなしで) 入れるか、または などのラッパーを使用して削除を管理してください。FoodeleteFooshared_ptr

于 2013-04-14T23:45:30.053 に答える