2016-05-14 2 views
2

У меня есть класс, предназначенный для регистрации, где отображается карта памяти. Когда я устанавливаю определенное местоположение на карте на некоторое количество, это дает мне нарушение доступа.Почему я получаю нарушение прав доступа при попытке использовать карту

Точная ошибка: Исключение выбрано в 0x003A5B4B в memorymapperexample.exe: 0xC0000005: Место обнаружения нарушения доступа 0x00000004.

Это мой класс. Addpair и clearlocation дают ошибки при вызове. Ключ карты - это указатель на пустоту, а значение карты - 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

Пожалуйста, отправьте сообщение [mcve]. –

+0

Хорошо, я добавил всю программу – fman

+1

* Я не понимаю, почему эта простая вещь .. * - Это просто? Перегрузка оператора 'new' ?? Вы проводите марафон перед тем, как научиться ходить? – PaulMcKenzie

ответ

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, который не дает разумного значения.

Отладка - чрезвычайно полезный навык.

Edit: компиляция с 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 - это плохая внутренняя структура, используемая для этого. (Фактически большая часть стандартных контейнеров вызовет аналогичные проблемы).

+0

Большое вам спасибо за информацию. Это имеет смысл. Не инициализирован memorymanager, поэтому он должен работать – fman

+0

@fman - 'memorymanager' * не * инициализирован. Во время инициализации ваша инициализация переменной 'map ' должна быть инициализирована, поскольку она является переменной-членом. Вы увидите, что ваша программа вызывает конструктор по умолчанию 'memorymanager' до того, как' main' был выполнен. – PaulMcKenzie

+0

О, вау, спасибо, что получил эту информацию. так что это бесконечная рекурсия – fman

Смежные вопросы