Вопрос по visual-studio-2010, visual-c++, c, memory-leaks, memory-management – Отладка повреждения памяти

6

Ранее я столкнулся с проблемой динамической памяти в C (visual studio). У меня была более или менее работающая программа, которая выдавала ошибку во время выполнения при освобождении одного из буферов. Это было явное повреждение памяти, программа перезаписывала конец буфера.

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

Есть ли какой-нибудь инструмент \ способ помочь отследить эту проблему? если бы программа вылетела сразу, я бы нашел проблему намного быстрее ...

пример вопроса:

int *pNum = malloc(10 * sizeof(int));

//                 ||
//                 \/    
for(int i = 0; i < 13; i++)
{
pNum[i] = 3;
}

// error....
free(pNum);
@stijn это помогает с точки зрения безопасности, а не для отладки ... он не падает сразу же ... и не показывает ошибку ... AK_
@ phant0m это был не реальный код, это был пример, и не мой код ... буфер был динамически распределен в зависимости от размера данных, и функция, которая вычисляет его размер, имела небольшую ошибку ... кроме того, мой вопрос о том, чтобы отследить проблему, а не предотвратить ее ... AK_
Не используете магические числа? phant0m
это не то, что "проверка безопасности буфера"; опция компилятора sin VS делает? stijn

Ваш Ответ

4   ответа
3

PageHeap, Это инструмент от Microsoft, который меняет работу распределителя. При включенном pageheap, когда вы вызываете malloc, выделение округляется до ближайшей страницы (блока памяти), и после него помещается дополнительная страница виртуальной памяти, для которой установлено значение no-read / no-write. Динамическая память, которую вы выделяете, выровнена так, что конец вашего буфера находится непосредственно перед концом страницы перед виртуальной страницей. Таким образом, если вы пересекаете буфер, часто на один байт, отладчик может легко его перехватить.

0

CheckPointer инструмент может помочь найти ошибки управления памятью. Работает с GCC 3/4 и диалектами Microsoft C.

Многие динамические контролеры только ловят доступoutside объекта, и то только в том случае, если объект выделен в куче. CheckPointer найдет ошибки доступа к памятиinside выделенный кучей объект; доступ к концу поля в структуре запрещен независимо от типа поля; большинство динамических контролеров не могут обнаружить такие ошибки. Это также найдет доступы от края местных жителей.

3

контрольные точки данных & quot; для этого. В вашем случае, когда программа падает, она может сначала жаловаться так:

Heap block at 00397848 modified at 0039789C past requested size of 4c

Затем снова запустите вашу программу и установите точку останова данных по адресу0039789C, Когда код пишет по этому адресу, выполнение остановится. Часто бывает, что я сразу же обнаружил ошибку.

Если ваша программа многократно выделяет и освобождает память, и это происходит именно по этому адресу, просто отключите освобождение:

_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_DELAY_FREE_MEM_DF);
2

Да, это именно тот тип ошибки, который пытаются обнаружить статические анализаторы кода. напримерsplint/PC-Lint

Вот список таких инструментов: http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis

Edit: При испытании шины на вашем фрагменте кода я получаю следующее предупреждение:

main.c:9:2: Possible out-of-bounds store: pnum[i]

Предположительно, это предупреждение помогло бы вам.

Похожие вопросы