Как управлять памятью самостоятельно?Необработанное исключение в 0x00423e3b в memory_manager.exe: 0xC0000005: расположение чтения нарушения доступа 0x00000004 - PullRequest
1 голос
/ 08 июля 2010

Необработанное исключение в 0x00423e3b в memory_manager.exe: 0xC0000005: Место чтения нарушения доступа 0x00000004.

Соус-файл Скачать: http://www.cppblog.com/Files/mymsdn/memory_manager_bug_vs2008_debug.zip Привет,

Я пытаюсь создать функцию менеджера памяти для решения некоторых проблем:

  1. Ссылка подсчитать новый / удалить счетчик при выделении памяти для проанализировать проблему утечки памяти.
  2. уменьшить фрагмент памяти.

Я написал класс memory_manager для управления выделением и освободить блок памяти. интерфейс:

void *allocate(size_t size); 
BOOL deallocate(void * ptr); 
// ... 

Я пытаюсь создать новое место размещения, чтобы заменить новое из система, поэтому я добавляю код ниже, чтобы сделать это.

#ifdef _DEBUG 


static memory_manager mm; 


inline void * __cdecl operator new(unsigned int size, 
                                   const char *file, int line) 
{ 
    void * res; 
    if((res = mm.allocate(size)) == 0) 
    { 
        // go to default allocator 
    } 
    return res; 
}; 


inline void __cdecl operator delete(void *p) 
{ 
    if(!mm.deallocate(p)) 
        return; 
}; 


inline void __cdecl operator delete[]( void * p ) 
{ 
    if(!mm.deallocate(p)) 
        return; 
}; 
#endif 


#ifdef _DEBUG 
#define DEBUG_NEW new(__FILE__, __LINE__) 
#else 
#define DEBUG_NEW new 
#endif 
#define new DEBUG_NEW 

Но я столкнулся с исключением во время выполнения, "Необработанное исключение в 0x00423e3b в memory_manager.exe: 0xC0000005: чтение о нарушении доступа местоположение 0x00000004. ".

Мой код memory_manager использовал код STL для управления моим менеджером структур.

Я отлаживаю свой код и вхожу в код STL, я обнаружил, что он использует CRT malloc для выделения памяти после деконструкции статической переменной "memory_manager mm", система выдает необработанное исключение.

Вопросы:

Я не знаю, как улучшить свой код, чтобы использовать новое / замененное размещение новый для моего кода?

Я не знаю, что произошло в деконструкции статической переменной?

Не знаю, есть ли лучший способ решить мои проблемы в начало этого поста?

У меня есть мысли о создании shared_ptr для решения этой проблемы, может быть как это:

shared_ptr sp_(new MyClass); 
// inner of shared_ptr: 

// 1. new MyClass use the system allocator to assign memory. 

// 2. In the constructor of the shared_ptr: 

// 2.1 copy the memroy of the (new MyClass) object into our memory: 

//       static memory_manager mm; 

//       void * p = mm.allocate(sizeof obj); 

//       memmove( from obj to p); 

//       delete obj; 

//       return p; 

// 3. Is it right? 

// 4. if it's a array, like new MyClass[10]; we must delete the object 

как это удалить [] obj? Как это отличить?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 08 июля 2010

Проблема в том, что вы перегружаете глобальные operator delete и operator delete[] в memory_manager_main.cpp.Как правило, если вы перегружаете один из операторов new или delete, вам, скорее всего, придется реализовать перегрузки для всех.

Затем внутренне в своем классе диспетчера памяти, который вы используете std::map и std::multimap, оба из которых опираются на класс std::allocator, если не указано иное.Это, по крайней мере, для версии, предоставляемой Microsoft для Visual Studio, основано на operator delete / operator new для освобождения и выделения.

Я не уверен, но вы, возможно, в конечном итоге удалили вещи с помощьюнеправильное удаление, или вы пытаетесь удалить материал с оператором delete в деструкторе std::map, используя operator delete, который зависит от экземпляра класса, который вы удаляете?

Вы могли бы реализоватьсобственный распределитель, использующий malloc / free, чтобы обойти эту проблему.

1 голос
/ 08 июля 2010
  1. ссылка подсчитывает новый / удаляемый счетчик при выделении памяти для анализа проблемы утечки памяти.

Я почти уверен, что MSVC уже поставляется с распределителем отладочной памяти, который позволяет обнаруживать такие проблемы. IIRC может быть дополнительно активирован для отладочных сборок.

Фактически, при поиске «визуальной отладки памяти студии» первая ссылка сразу приводит к этой странице : включение обнаружения утечки памяти.

  1. уменьшить фрагмент памяти.

Стандартные распределители памяти довольно устойчивы к фрагментации памяти. Вам может понадобиться альтернативный распределитель памяти, только если вы пишете приложение, которое, как ожидается, будет работать месяцами / годами без перерыва. Но даже для случаев замена распределителя памяти является поверхностной и менее надежной по сравнению с простым распределением ресурсов заранее: выделите все ресурсы, которые могут понадобиться сразу после запуска приложения.

Я не знаю, как улучшить свой код, чтобы использовать новое место размещения / заменить новое в моем коде?

Вам не нужно делать ничего особенного. Размещение new не запускает выделение памяти - это просто причудливый способ вызвать конструктор для фрагмента сырой памяти. Если необработанная память была выделена ранее с помощью new, значит, вы уже настроены.

Я не знаю, что произошло при деконструкции статической переменной?

Управление памятью не задействовано. Статические переменные живут в сегменте данных, а не в куче.

Не знаю, есть ли лучший способ решить мои проблемы в начале этого поста?

Моим диким предположением (и это обычная ошибка новичка) является то, что ваша реализация диспетчера памяти использует динамическую память и рекурсивно вызывает себя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...