返回后std :: map值丢失了

时间:2013-04-14 23:26:37

标签: c++ map

如何在将地图从一个功能传递到另一个功能时正确处理内存。

我有一个函数可以返回它构建的地图。值对象是Class foo。 我在三个不同的位置打印foo,所有这些都给出了不同的值。第一次,它给出了正确的价值观。第二个和第三个是垃圾。

我知道我必须在适当的位置制作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;  

Click here查看我的实际代码。

更新:未使用'new'运算符分配Foo的成员变量。因此,一旦超出范围,它们就会超出范围并具有垃圾值。

3 个答案:

答案 0 :(得分:1)

确保您实际使用正确的值创建std::pair

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

或者使用std::make_pair

myMap.insert(std::make_pair(v, b));

答案 1 :(得分:1)

你的代码中有很多小错误(我认为这只是错别字)。我修复了这些并提供了Foo类,它编译并运行正常,在所有三个地方打印正确的值:

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

Click here查看输出。

因此,问题必须出在你未提及的问题中。为了能够进一步提供帮助,我们需要查看真实的代码。

答案 2 :(得分:0)

你在哪里发表评论&#34;在这里打印&#34;你怎么编译它?您无法通过其中任何一个地方的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来创建Foo个对象,所以必须在某个地方使用delete进行清理,否则你的程序将内存泄漏。因此,人们通常不会将指针直接放入地图或列表中。相反,只需将Foo对象的副本放入(无指针),或者使用诸如shared_ptr之类的包装来管理删除。