为什么在尝试使用地图时会出现访问违规
Why do I get access violation when trying to use a map
我这里有一个类,用来记录内存映射的位置。当我将地图上的特定位置设置为某个数字时,就会出现访问违规。
确切的错误是在memorymapperexample.exe:0xC0000005:读取位置0x00000004时发生0x003A5B4B异常。
这是我的课。Addpair和clearlocation在调用时会出现错误。map键是一个void指针,map值是一个int。我不明白为什么这个简单的东西不起作用。
#include <map>
#include <unordered_map>
#include <string>
#include <iostream>
#include <memory>
using namespace std;
template <typename T>
class MallocAllocator
{
private:
map<void *, int> ord;
int total;
public:
typedef T value_type;
MallocAllocator() { }
template <typename U> MallocAllocator(const MallocAllocator<U>& other) {}
T* allocate(size_t count)
{
return (T*)malloc(count * sizeof(T));
}
void deallocate(T* object, size_t n)
{
void* ptr = reinterpret_cast<void*>(object);
free(ptr);
}
void addpair(void* a, int b)
{
ord[a] = b; //ERROR HERE
}
void clearlocation(void * a)
{
ord[a] = 0; //ERROR HERE TOO
}
};
MallocAllocator<void*> memoryManager;
void* operator new(size_t size)
{
cout << "Allocating memory..." << endl;
auto newObject = memoryManager.allocate(size);
memoryManager.addpair(newObject, size);
memoryManager.clearlocation(newObject);
return newObject;
}
void operator delete(void* objectPtr) noexcept
{
cout << "DEAllocating memory..." << endl;
void** ptr = reinterpret_cast<void**>(objectPtr);
memoryManager.deallocate(ptr, 0);
//free(objectPtr);
}
int main()
{
int * ima = new int(99);
delete ima;
return 1;
}
发现您的问题。通过VS运行它给了我这个堆栈跟踪。
bleh.exe!std::_Tree<std::_Tmap_traits<void * __ptr64,int,std::less<void * __ptr64>,std::allocator<std::pair<void * __ptr64 const,int> >,0> >::_Lbound<void * __ptr64>(void * const & _Keyval) Line 2090 C++
bleh.exe!std::_Tree<std::_Tmap_traits<void * __ptr64,int,std::less<void * __ptr64>,std::allocator<std::pair<void * __ptr64 const,int> >,0> >::lower_bound(void * const & _Keyval) Line 1549 C++
bleh.exe!std::map<void * __ptr64,int,std::less<void * __ptr64>,std::allocator<std::pair<void * __ptr64 const,int> > >::_Try_emplace<void * __ptr64 const & __ptr64>(void * const & _Keyval) Line 210 C++
bleh.exe!std::map<void * __ptr64,int,std::less<void * __ptr64>,std::allocator<std::pair<void * __ptr64 const,int> > >::try_emplace<>(void * const & _Keyval) Line 230 C++
bleh.exe!std::map<void * __ptr64,int,std::less<void * __ptr64>,std::allocator<std::pair<void * __ptr64 const,int> > >::operator[](void * const & _Keyval) Line 339 C++
bleh.exe!MallocAllocator<void * __ptr64>::addpair(void * a, int b) Line 80 C++
bleh.exe!operator new(unsigned __int64 size) Line 97 C++
[External Code]
bleh.exe!MallocAllocator<void * __ptr64>::MallocAllocator<void * __ptr64>() Line 66 C++
bleh.exe!`dynamic initializer for 'memoryManager''() Line 89 C++
[External Code]
堆栈显示,当有东西调用new
时,程序正在初始化memoryManager
(我猜std::map
正在尝试分配一些东西)。但当然,您已经重载了new
以使用尚未完全初始化的memoryManager
!真倒霉它在试图获取std::map
的根节点时抛出错误,该根节点没有给出合理的值。
调试是一项非常有用的技能。
编辑:使用g++ -std=c++11 bleh.cpp
编译并通过gdb
运行会给我一个不同但同样令人不安的结果。
#0 0x00007ffff756a648 in _IO_new_file_xsputn (f=0x7ffff78b0400 <_IO_2_1_stdout_>, data=0x402597, n=20) at fileops.c:1320
#1 0x00007ffff755fe6d in __GI__IO_fwrite (buf=<optimized out>, size=1, count=20, fp=0x7ffff78b0400 <_IO_2_1_stdout_>) at iofwrite.c:43
#2 0x00007ffff7b7f63e in std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff7b7f947 in std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x0000000000400d11 in operator new(unsigned long) ()
#5 0x000000000040228b in __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<void* const, int> > >::allocate(unsigned long, void const*) ()
#6 0x0000000000402142 in std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<void* const, int> > > >::allocate(std::allocator<std::_Rb_tree_node<std::pair<void* const, int> > >&, unsigned long) ()
#7 0x0000000000401d75 in std::_Rb_tree<void*, std::pair<void* const, int>, std::_Select1st<std::pair<void* const, int> >, std::less<void*>, std::allocator<std::pair<void* const, int> > >::_M_get_node() ()
#8 0x00000000004015cd in std::_Rb_tree_node<std::pair<void* const, int> >* std::_Rb_tree<void*, std::pair<void* const, int>, std::_Select1st<std::pair<void* const, int> >, std::less<void*>, std::allocator<std::pair<void* const, int> > >::_M_create_node<std::piecewise_construct_t const&, std::tuple<void* const&>, std::tuple<> >(std::piecewise_construct_t const&, std::tuple<void* const&>&&, std::tuple<>&&) ()
#9 0x0000000000401368 in std::_Rb_tree_iterator<std::pair<void* const, int> > std::_Rb_tree<void*, std::pair<void* const, int>, std::_Select1st<std::pair<void* const, int> >, std::less<void*>, std::allocator<std::pair<void* const, int> > >::_M_emplace_hint_unique<std::piecewise_construct_t const&, std::tuple<void* const&>, std::tuple<> >(std::_Rb_tree_const_iterator<std::pair<void* const, int> >, std::piecewise_construct_t const&, std::tuple<void* const&>&&, std::tuple<>&&) ()
#10 0x0000000000401122 in std::map<void*, int, std::less<void*>, std::allocator<std::pair<void* const, int> > >::operator[](void* const&) ()
#11 0x0000000000400ee4 in MallocAllocator<void*>::addpair(void*, int) ()
#12 0x0000000000400d4a in operator new(unsigned long) ()
#13 0x000000000040228b in __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<void* const, int> > >::allocate(unsigned long, void const*) ()
#14 0x0000000000402142 in std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<void* const, int> > > >::allocate(std::allocator<std::_Rb_tree_node<std::pair<void* const, int> > >&, unsigned long) ()
#15 0x0000000000401d75 in std::_Rb_tree<void*, std::pair<void* const, int>, std::_Select1st<std::pair<void* const, int> >, std::less<void*>, std::allocator<std::pair<void* const, int> > >::_M_get_node() ()
#16 0x00000000004015cd in std::_Rb_tree_node<std::pair<void* const, int> >* std::_Rb_tree<void*, std::pair<void* const, int>, std::_Select1st<std::pair<void* const, int> >, std::less<void*>, std::allocator<std::pair<void* const, int> > >::_M_create_node<std::piecewise_construct_t const&, std::tuple<void* const&>, std::tuple<> >(std::piecewise_construct_t const&, std::tuple<void* const&>&&, std::tuple<>&&) ()
#17 0x0000000000401368 in std::_Rb_tree_iterator<std::pair<void* const, int> > std::_Rb_tree<void*, std::pair<void* const, int>, std::_Select1st<std::pair<void* const, int> >, std::less<void*>, std::allocator<std::pair<void* const, int> > >::_M_emplace_hint_unique<std::piecewise_construct_t const&, std::tuple<void* const&>, std::tuple<> >(std::_Rb_tree_const_iterator<std::pair<void* const, int> >, std::piecewise_construct_t const&, std::tuple<void* const&>&&, std::tuple<>&&) ()
# ... ad inifintum ...
这一次,程序正在通过它的外观设置它的一个流std::cout
。并尝试分配内存。看起来memoryManager
设置正确或实际初始化正确。无论哪种方式,当它试图分配一些东西时,分配器都会在std::map
中创建一个新节点。这需要内存分配。这需要创建一个新节点。。。看到我拿着这个去哪儿了吗?堆栈跟踪像这样重复了很长一段时间。
总而言之,std::map
是一个糟糕的内部结构。(事实上,大多数标准容器都会产生类似的问题)。
相关文章:
- 如何包装(撰写)增强 hana 地图并访问括号运算符(运算符 [])?
- 以C++访问矢量中的地图元素
- 如何访问具有地图的2D矢量?
- 如何从地图访问数组的元素?
- 如何访问整个地图的值
- std::在地图上查找无法正常工作并循环访问地图的键和值
- 尝试访问地图中元素时的错误
- 如何从公共函数成员访问地图私有成员
- 以对为键访问地图
- 使用for_each或变换访问地图的第二个元素
- 如何访问地图中的矢量
- 使用 C++98 标准访问地图
- 如何在映射向量中循环访问地图
- 访问地图数据结构中的结构元素
- 访问地图内部的矢量,该矢量位于另一个地图内
- 访问地图的一个"item"
- 访问地图元素
- 继承可以't访问地图
- 访问地图元素会增加其分配的内存大小
- 如何访问地图