C++ 从函数返回时指针损坏
TL;DR :当我在OSX优诗美地国家公园下运行一个Mac上的C++程序时,指针在函数返回时会损坏。我如何阻止它发生?(为什么?)C++ 从函数返回时指针损坏,c++,macos,pointers,memory,c++98,C++,Macos,Pointers,Memory,C++98,TL;DR :当我在OSX优诗美地国家公园下运行一个Mac上的C++程序时,指针在函数返回时会损坏。我如何阻止它发生?(为什么?) 在中,我有一个类型为category\u map的数据结构,它实际上只是一个 map<string, list<pair<string, T> > > 但是,当我在Mac(OS X Yosemite)上编译并运行代码时,而不是在Linux上,在从该函数清除的过程中,某些东西会写入内存中的同一位置,因此返回的指针(存储在下面代码
在中,我有一个类型为
category\u map
的数据结构,它实际上只是一个
map<string, list<pair<string, T> > >
但是,当我在Mac(OS X Yosemite)上编译并运行代码时,而不是在Linux上,在从该函数清除的过程中,某些东西会写入内存中的同一位置,因此返回的指针(存储在下面代码列表中的变量ip
中)已损坏。例如,它可能变成0x3000100809c00
或0x5000100809c00
。损坏的指针始终是原始指针,在8字节地址的第二个最高有效字节中设置了一个或几个额外的位
int main(const int argc, const char** argv) {
category_map<int*> imap;
int a;
imap.add("Q1", "m", &a);
imap.add("Q1", "r", &a);
imap.add("Q2", "m", &a);
int* ip = imap.get("Q1");
cerr << "return value: " << val_loc_string<int*>(ip) << endl;
cout << *ip << endl;
}
()但这没有多大帮助,因为它不是C/C++函数的一部分,我的汇编不够流利,无法理解它在大规模上做什么,而且它是垃圾,所以我无法将代码放入上下文中。(我还捕获了损坏指针的指令之前的代码,以防由于某种原因而有所帮助。)
由于我仅使用指针类型实例化category\u map
,因此我可以将get
的返回类型更改为T
(而不是T&
),这似乎解决了(或至少解决了)问题。但是,如果数据结构能够容纳大型对象并通过引用返回它们,那么它会使数据结构更加普遍有用,我认为这应该是可能的。另外,无论我在编码过程中犯了什么错误,我都希望理解,这样我就不会再犯同样的错误了。有谁能指出我做错了什么,以及在不更改API的情况下修复它的正确方法吗
list_type the_list = map_iterator->second;
您可以复制map\u iterator->second
<代码>列表是一个函数本地对象。然后
T& p = the_list.front().second;
return p;
返回对某个对象的引用,该对象与此函数本地对象一样长,并且在函数离开时被销毁。参考悬挂着
在我看来,你似乎不打算复制这份名单,所以
// +------ const because get() is const-qualified
// v v-- reference
list_type const &the_list = map_iterator->second;
// v-- const because the_list is const
T const& p = the_list.front().second;
如果可以使get()常量
返回一个T常量&
1,则应该修复它。否则,您会遇到从const
成员函数返回对非const成员的引用的问题;这将破坏常量的正确性,因此是禁止的(如果允许的话,您可以通过该引用更改常量对象)
1您还可以使get const()
返回一个值而不是一个引用,但似乎没有理由强制进行该复制。使用
list_type the_list = map_iterator->second;
您可以复制map\u iterator->second
<代码>列表是一个函数本地对象。然后
T& p = the_list.front().second;
return p;
返回对某个对象的引用,该对象与此函数本地对象一样长,并且在函数离开时被销毁。参考悬挂着
在我看来,你似乎不打算复制这份名单,所以
// +------ const because get() is const-qualified
// v v-- reference
list_type const &the_list = map_iterator->second;
// v-- const because the_list is const
T const& p = the_list.front().second;
如果可以使get()常量
返回一个T常量&
1,则应该修复它。否则,您会遇到从const
成员函数返回对非const成员的引用的问题;这将破坏常量的正确性,因此是禁止的(如果允许的话,您可以通过该引用更改常量对象)
1您还可以使get const()
返回一个值而不是一个引用,但似乎没有理由强制进行该复制