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

时间:2016-05-14 01:30:42

标签: c++ dictionary

我这里有一个类,用于记录内存映射的位置。当我在地图上将特定位置设置为某个数字时,会给我一个访问冲突。

精确错误是在memorymapperexample.exe中0x003A5B4B处抛出异常:0xC0000005:访问冲突读取位置0x00000004。

这是我的班级。调用时,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;
}

1 个答案:

答案 0 :(得分:4)

找到你的问题。通过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] 

当某些内容调用memoryManager时,该堆栈显示该程序处于new的初始化状态(我猜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中创建一个新节点。这需要内存分配。这需要创建一个新节点...看看我在哪里?堆栈跟踪像这样重复了很长一段时间。

总而言之,library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.numeric_std.ALL; entity test44_vhdl is Port ( row : in std_logic_vector (1 downto 0); slice : out std_logic_vector (3 downto 0)); end test44_vhdl; architecture Behavioral of test44_vhdl is type oneD is array (1 to 3) of integer range 0 to 15; constant table: oneD := (3, 9, 13); begin slice <= std_logic_vector(to_unsigned(table(to_integer(unsigned(row))), slice'length)); end Behavioral; 是一个糟糕的内部结构。 (实际上大多数标准容器会导致类似的问题)。