简体   繁体   English

为什么在尝试使用地图时出现访问冲突

[英]Why do I get access violation when trying to use a map

I have a class here meant to log where memory is mapped. 我这里有一个用于记录内存映射位置的类。 When I set a specific location on the map to some number, it give me an access violation. 当我在地图上将特定位置设置为某个数字时,它会给我造成访问冲突。

The exact error is Exception thrown at 0x003A5B4B in memorymapperexample.exe: 0xC0000005: Access violation reading location 0x00000004. 确切的错误是在memorymapperexample.exe中的0x003A5B4B引发异常:0xC0000005:访问冲突读取位置0x00000004。

This is my class. 这是我的课。 Addpair and clearlocation give errors when called. Addpair和clearlocation在调用时产生错误。 The map key is a void pointer and the map value is a int. 映射键是一个void指针,映射值是一个int。 I don't understand why this simple thing is not working. 我不明白为什么这个简单的事情不起作用。

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

Found your problem. 找到了你的问题。 Running it through VS gave me this stack trace. 通过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] 

The stack reveals that the program is in the initialization of memoryManager when something calls new (I guess std::map is trying to allocate something). 堆栈显示,当某些东西调用new时,程序处于memoryManager的初始化中(我猜std::map试图分配一些东西)。 But of course, you've overloaded new to use memoryManager which has not been fully initialized yet! 但是,当然,您已经使用了尚未完全初始化的memoryManager重载了new Bummer. 游民。 And it throws the error when trying to get the root node of the std::map which doesn't give a sensible value. 当尝试获取没有给出合理值的std::map的根节点时,它将引发错误。

Debugging is an enormously useful skill. 调试是一项非常有用的技能。

Edit: compiling with g++ -std=c++11 bleh.cpp and running through gdb gives me a different but equally troubling result. 编辑:使用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 ...

This time, the program is setting up one of its streams std::cout by the looks of it. 这次,该程序通过其外观来设置其流std::cout之一。 And tries to allocate memory. 并尝试分配内存。 Looks like memoryManager happened to be set up right or actually initialized properly. 看起来memoryManager恰好设置正确或实际上已正确初始化。 Either way when it tries to allocate something your allocator causes a new node to be created in std::map . 无论哪种方式,当它尝试分配内容时,分配器都会在std::map创建一个新节点。 Which requires memory allocation. 这需要内存分配。 Which requires creating a new node... See where I'm going with this? 哪个需要创建一个新节点...看看我要怎么做? The stack trace repeats like this for quite a while. 堆栈跟踪会像这样重复一段时间。

All in all, std::map is a bad internal structure to use for this. 总而言之, std::map是用于此目的的不良内部结构。 (Actually most of the standard containers would cause similar problems). (实际上,大多数标准容器都会引起类似的问题)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM