如何在将地图从一个功能传递到另一个功能时正确处理内存。
我有一个函数可以返回它构建的地图。值对象是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的成员变量。因此,一旦超出范围,它们就会超出范围并具有垃圾值。
答案 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
之类的包装来管理删除。