Как использовать valgrind linux
Обновлено: 21.11.2024
Хотя C – очень полезный и мощный язык, отлаживать его бывает сложно. Конкретная проблема, с которой вы, вероятно, сталкивались в какой-то момент, — это ошибки памяти. Мы уже говорили о gdb, который может оказаться полезным, если ваша программа постоянно дает сбой или выводит неверный результат. Однако иногда вы подозреваете, что проблема связана с ошибкой памяти, но она не вызывает segfault, и вы не хотите устанавливать много точек останова и выполнять пошаговое выполнение в gdb. Другая распространенная проблема, с которой вы можете столкнуться, — это программа с утечкой памяти: где-то вы вызываете malloc, но никогда не вызываете free. Valgrind — это программа, которая поможет вам решить обе проблемы.
Valgrind установлен на машинах отдела. Чтобы вызвать его для исполняемого файла с именем a.out, вы просто запускаете команду valgrind ./a.out (с любыми аргументами, которые могут понадобиться вашей программе). Как и при использовании gdb, вы должны скомпилировать свою программу с флагом -g, чтобы вы могли видеть номера строк в выводе. Вы также можете выполнять отладку с отключенными оптимизациями (-O0), так как если они у вас включены, номера строк могут быть неточными, и вы можете иногда сталкиваться с ложными тревогами.
Пример 1: чтение/запись после конца массива
Одной из распространенных ошибок является обращение к элементам после конца массива. В отличие от java, которая выдает исключение, когда вы пытаетесь это сделать, ваша программа на языке C может давать сбой или продолжать работать, выдавая правильный или неправильный результат — иногда с разными результатами в разных запусках. Это затрудняет обнаружение такого рода проблемы. Вот как можно использовать valgrind для поиска ошибки:
Пример 1 | Вывод |
---|
Ваши выходные данные могут немного отличаться в зависимости от компьютера и версии valgrind и установленных библиотек, но должны содержать те же типы ошибок. Если вы изучите выходные данные, вы увидите, что в списке указана 1 ошибка (вам не нужно беспокоиться о подавленных ошибках). Valgrind выводит ошибку (Неверная запись размера 4), а также стек. В нем также перечислены файл, функция и строка, в которой этот массив был преобразован в malloc.
Пример 2: чтение неинициализированной памяти
Еще одна распространенная проблема – забывание инициализировать переменную или массив перед их использованием.
Пример 2 | Вывод |
---|
Обратите внимание, что выходные данные программы и выходные данные valgrind чередуются; чтобы обойти это, удобно перенаправить вывод в отдельный файл. На этот раз сообщается об ошибках для неинициализированных значений, а valgrind указывает, где происходит доступ (строка 11 примера 2.c). Если вы запустите с параметром --track-origins=yes, valgrind предоставит дополнительную информацию о том, откуда взялись неинициализированные значения.
Пример 3: утечки памяти
Valgrind включает функцию проверки утечек памяти. Если опция не указана, будет показана сводка кучи, в которой будет указано, есть ли какая-либо память, которая была выделена, но не освобождена. Если вы используете параметр --leak-check=full, это даст больше информации.
Пример 3 | Вывод |
---|
Если вы видите утечки, обозначенные как все еще доступные, это, как правило, не указывает на серьезную проблему, поскольку память, вероятно, все еще использовалась в конце программы. Тем не менее, любые утечки, перечисленные как «определенно потерянные», должны быть устранены (так же, как и те, что указаны как «косвенно потерянные» или «возможно потерянные» — «косвенно потерянные» произойдут, если вы сделаете что-то вроде освобождения корневого узла дерева, но не самого узла). остальная часть, а «возможно, потеряна» обычно указывает, что память фактически потеряна). Например, вы можете столкнуться с примером, подобным приведенному выше, если у вас есть функция, которая выделяет буфер (возможно, для хранения строки) и возвращает его, но вызывающая программа никогда не освобождает память после ее завершения. Если такая программа работает долго, она выделяет много памяти, которая ей не нужна.
Чем valgrind НЕ является
Хотя valgrind — чрезвычайно полезная программа, она не сообщит вам чудесным образом обо всех ошибках памяти в вашей программе. Есть несколько ограничений, которые вы должны иметь в виду. Он не выполняет проверку границ стека/статических массивов (тех, которые не выделены с помощью malloc), поэтому возможно иметь программу, которая ведет себя плохо, не генерируя никаких ошибок valgrind. Например:
Эта программа имеет ошибку памяти, в результате чего значение x в конце равно 10, а не 0. Однако valgrind не сообщит об ошибках.
Более серьезное ограничение, с которым вы столкнетесь, заключается в том, что valgrind проверяет программы динамически, т. е. во время фактического выполнения программы проверяет, действительно ли при этом выполнении возникли какие-либо утечки.Это означает, что если вы запускаете valgrind для определенного набора входных данных, который не вызывает каких-либо неправильных обращений к памяти или утечки памяти, valgrind не сообщит об ошибках, даже если ваша программа действительно содержит ошибки. Например:
В этой программе есть ошибка: если пользователь вводит длинную строку, буфер str переполняется. Обратите внимание, что вы никогда не должны использовать gets именно по этой причине. Если вы запустите эту программу через valgrind, вы получите ошибку памяти, если введете строку длиннее 10 символов. Однако, если вы введете более короткую строку, valgrind не сообщит об ошибках, даже если в программе есть ошибки! Если вы хотите быть достаточно уверены, что вы ловите все ошибки памяти, вы должны запускать valgrind для различных входных данных, особенно крайних случаев, поскольку именно там вы, скорее всего, допустили ошибку, например доступ за границы массива. .
Исправлять ошибки рекомендуется начинать сверху; исправление ошибки, возникшей ранее, скорее всего, также устранит множество более поздних ошибок.
Время от времени вы можете столкнуться с ложным срабатыванием — ошибкой, даже если с вашей программой все в порядке. Однако в подавляющем большинстве случаев любая ошибка, о которой сообщается, реальна, и вы должны ее исправить. Будьте очень осторожны, считая ошибку «ложноположительной», так как гораздо более вероятно, что вы допустили ошибку.
Еще одно замечание относительно valgrind: ваши программы будут выполняться дольше (например, в 20–30 раз дольше), а также будут использовать больше памяти.
Подробнее
Если вам интересно узнать о valgrind, вы можете посетить веб-сайт valgrind, особенно ответы на часто задаваемые вопросы.
Присылайте любые исправления или вопросы по адресу lena@cs. Последнее обновление: 16 марта 2011 г.
Набор инструментов Valgrind предоставляет ряд инструментов для отладки и профилирования, которые помогут вам сделать ваши программы быстрее и точнее. Самый популярный из этих инструментов называется Memcheck. Он может обнаруживать многие ошибки, связанные с памятью, которые распространены в программах C и C++ и могут привести к сбоям и непредсказуемому поведению.
В остальной части этого руководства содержится минимум информации, необходимой для обнаружения ошибок памяти в вашей программе с помощью Memcheck. Полную документацию по Memcheck и другим инструментам см. в Руководстве пользователя.
2. Подготовка программы
Скомпилируйте свою программу с параметром -g, чтобы включить отладочную информацию, чтобы сообщения об ошибках Memcheck содержали точные номера строк. Использование -O0 также является хорошей идеей, если вы можете мириться с замедлением. С -O1 номера строк в сообщениях об ошибках могут быть неточными, хотя, вообще говоря, запуск Memcheck на коде, скомпилированном с -O1, работает довольно хорошо, а улучшение скорости по сравнению с запуском -O0 весьма значительно. Использование -O2 и выше не рекомендуется, так как Memcheck иногда сообщает об ошибках с неинициализированными значениями, которых на самом деле не существует.
3. Запуск вашей программы под Memcheck
Если вы обычно запускаете свою программу следующим образом:
Используйте эту командную строку:
Memcheck – это инструмент по умолчанию. Параметр --leak-check включает подробный детектор утечки памяти.
Ваша программа будет работать намного медленнее (например, в 20-30 раз), чем обычно, и будет использовать намного больше памяти. Memcheck будет выдавать сообщения об обнаруженных ошибках и утечках памяти.
4. Интерпретация вывода Memcheck
Вот пример программы на C в файле с именем a.c с ошибкой памяти и утечкой памяти.
Большинство сообщений об ошибках выглядят следующим образом, описывая проблему 1, переполнение блока кучи:
На что следует обратить внимание:
В каждом сообщении об ошибке содержится много информации; прочитайте внимательно.
19182 — это идентификатор процесса; обычно это неважно.
В первой строке ("Недопустимая запись") сообщается, что это за ошибка. Здесь программа записывает часть памяти, которой не должно быть из-за переполнения блока кучи.
Под первой строкой находится трассировка стека, показывающая, где возникла проблема. Трассировки стека могут быть довольно большими и сбивать с толку, особенно если вы используете C++ STL. Чтение их снизу вверх может помочь. Если трассировка стека недостаточно велика, используйте параметр --num-callers, чтобы увеличить ее.
Кодовые адреса (например, 0x804838F) обычно не важны, но иногда имеют решающее значение для отслеживания более странных ошибок.
Некоторые сообщения об ошибках содержат второй компонент, описывающий задействованный адрес памяти. Это показывает, что записанная память находится сразу за концом блока, выделенного с помощью malloc() в строке 5 примера.c.
Исправлять ошибки стоит в том порядке, в котором о них сообщается, так как более поздние ошибки могут быть вызваны более ранними ошибками. Неспособность сделать это является распространенной причиной проблем с Memcheck.
Сообщения об утечке памяти выглядят следующим образом:
Трассировка стека показывает, где была выделена утечка памяти. К сожалению, Memcheck не может сказать вам, почему произошла утечка памяти. (Игнорируйте "vg_replace_malloc.c", это деталь реализации.)
"определенно потерян": в вашей программе происходит утечка памяти - исправьте это!
"вероятно, потеряно": в вашей программе происходит утечка памяти, если только вы не делаете забавные вещи с указателями (например, перемещаете их так, чтобы они указывали на середину блока кучи).
Memcheck также сообщает об использовании неинициализированных значений, чаще всего с сообщением "Условный переход или перемещение зависит от неинициализированных значений". Может быть трудно определить основную причину этих ошибок. Попробуйте использовать параметр --track-origins=yes, чтобы получить дополнительную информацию. Это заставляет Memcheck работать медленнее, но дополнительная информация, которую вы получаете, часто экономит много времени на выяснение того, откуда берутся неинициализированные значения.
Если вы не понимаете сообщение об ошибке, обратитесь к разделу «Объяснение сообщений об ошибках от Memcheck» в Руководстве пользователя Valgrind, в котором приведены примеры всех сообщений об ошибках, которые выдает Memcheck.
5. Предостережения
Memcheck не идеален; иногда он выдает ложные срабатывания, и существуют механизмы для их подавления (см. Подавление ошибок в Руководстве пользователя Valgrind). Тем не менее, как правило, в 99% случаев это правильно, поэтому вам следует опасаться игнорировать его сообщения об ошибках. В конце концов, вы же не будете игнорировать предупреждающие сообщения, выдаваемые компилятором, верно? Механизм подавления также полезен, если Memcheck сообщает об ошибках в коде библиотеки, которые вы не можете изменить. Набор подавления по умолчанию скрывает многие из них, но вы можете встретить и другие.
Memcheck не может обнаружить все ошибки памяти в вашей программе. Например, он не может обнаруживать операции чтения или записи вне допустимого диапазона в массивы, выделенные статически или в стеке. Но он должен обнаруживать множество ошибок, которые могут привести к сбою вашей программы (например, вызвать ошибку сегментации).
6. Подробнее
Пожалуйста, ознакомьтесь с часто задаваемыми вопросами по Valgrind и руководством пользователя Valgrind, в которых содержится гораздо больше информации. Обратите внимание, что другие инструменты в дистрибутиве Valgrind можно вызывать с помощью параметра --tool.
Valgrind — это детектор неправильного управления памятью. Мы можем знать об утечках памяти и ошибках освобождения памяти. Это многоцелевой код. Также известно, что это инструмент отладки памяти для Linux. Этот детектор имеет важную функцию запуска вашей программы в среде памяти Valgrind, а также отслеживает использование памяти. Если в некоторых случаях написания кода такая ситуация возникает, когда вы используете память, которая еще не инициализирована, или вы забыли освободить указатель, эти вызывающие ошибку эффекты обнаруживаются Valgrind. В этой статье основное внимание будет уделено использованию Valgrind для обнаружения подобных проблем.
Valgrind зависит от операционной системы, поскольку его можно запустить только в операционной системе Linux. Valgrind — это набор инструментов для обнаружения памяти с открытым исходным кодом. Он широко используется и является более мощным, чем другие инструменты, такие как memwatch, mtrace и т. д., которые выполняют те же функции, что и Valgrind. Хотя C++ — очень мощный и полезный язык программирования, он требует больших усилий для отладки и выполнения. Тем не менее, иногда возникают ошибки памяти, что является конкретной проблемой. Точно так же существует еще одна ошибка — утечка памяти. Valgrind — это специальная программа, которая поможет вам решить обе проблемы.
Установка Valgrind
При работе на платформе Linux требуется множество новых программ для выполнения определенных программ в этой операционной системе. Например, при использовании терминала вам нужна оснастка, подходящая для установки многих других программ. Точно так же Valgrind также устанавливается на терминал с помощью команды «sudo-apt».
Это займет некоторое время, но, в конце концов, он будет успешно установлен в вашей системе.
Некоторые инструкции по использованию Valgrind
Тестируемая программа или приложение добавляется через компилятор, который компилирует программу. Используется «-g», поскольку он также является компилятором для программ C++.
Результирующее значение записи обнаружения отображается как вывод на терминале. Кроме того, результирующее значение можно сохранить в файл.
Если вам нужны дополнительные инструкции или вам нужна помощь в использовании какой-либо конкретной команды, вы можете выполнить Valgrind –h, что даст вам интерфейс справочного терминала.
Принцип обнаружения памяти Valgrind
Valgrind использует виртуальную среду для реализации программ. Программа или приложение, которое необходимо протестировать, работает в этой виртуально созданной среде. Функция Valgrind состоит в том, чтобы отслеживать приложение, его использование и освобождение памяти в режиме реального времени, а также записывать информацию, которая может указывать на некоторые отклонения в памяти. В Valgrind есть компонент обнаружения памяти, Memcheck. Он поддерживает множество функций. Некоторые из них перечислены ниже:
- Место в памяти не выделено.
- Доступ к памяти превысил заданный лимит.
- Место памяти постоянно освобождается.
- Применение пространства памяти и освобождение памяти не совпадают.
Memcheck может проверить многие проблемы, поскольку это самый мощный компонент Valgrind.
- Переменные, которые не инициализированы
- Malloc() с функциональностью любого free()
- Указатель кучи, который обращается к недопустимой памяти.
- Теперь мы объясним работу Valgrind на нескольких примерах
Неинициализированная память
Эта проблема возникает при написании программы с использованием какой-либо одиночной переменной или массива. И вы забыли объявить и инициализировать массив в начале. И во время использования вы не очень хорошо осведомлены об этой проблеме забывания. Эта ошибка определяется Valgrind. Для пояснения примера мы взяли программу на C++.
Первый шаг – использование библиотеки STD.
Здесь вы можете видеть, что значение переменной не присваивается, а передается массиву, и аналогичным образом эти значения печатаются с использованием цикла for. Здесь мы забыли присвоить значение переменной. Ошибка возникает, когда для отображения значений выбран пустой массив.
Теперь мы выполним этот код на терминале Ubuntu. Мы будем использовать компилятор g++ для компиляции кода. В отличие от простого кода на C, здесь мы будем использовать ключевое слово «Valgrind’s».
Теперь эта команда выведет из памяти часть используемой страницы. Сначала мы получим описание «Memcheck». Затем отображаются подробности о неинициализированном значении. В этой части вы можете видеть, что указан номер строки, в которой произошла ошибка. Здесь номер строки «11».
Обнаружение утечек памяти
Предположим, у вас есть программа, которая содержит функцию malloc() no free(). Это приведет к утечке памяти. Вот пример исходного кода C++.
В основной программе указатель символьного типа используется с функцией malloc. Даже небольшая программа также отвечает за выявление утечек памяти. Теперь мы увидим результат.
Контент вывода совпадает с выводом предыдущего в некоторых аспектах, поэтому мы отобразили только часть утечек памяти, чтобы иметь полный фокус.
Теперь мы скомпилируем приведенный выше код и выполним его через команду.
Эта команда покажет следующие результаты. Здесь вы можете заметить, что отображается количество потерянных байтов. Строка, в которой произошла ошибка, также отображается в последней строке результирующих значений.
Этот результат также содержит сводку утечки, которая объясняет общее количество байтов, потерянных прямо или косвенно; каким бы ни было описание, оно кратко поясняется в результате.
Обнаружение недопустимого доступа к памяти
Иногда такие условия встречаются, когда исходный код содержит ошибку, указатель мы используем для доступа к не привязанной области памяти. Эта ошибка обнаружена memcheck.
В приведенном выше коде видно, что мы использовали указатель ptr, пытающийся получить доступ к ячейке памяти, выходящей за границы.
Вывод показывает, что размер недействителен. Поскольку мы объявили массив размером [10]. И указатель обращается к слоту 11, который находится вне диапазона, который мы объявили.
Обнаружение висячих указателей
Это те указатели, которые указывают на уже освобожденную память.
Здесь мы сначала освобождаем место; даже после освобождения места код пытается получить доступ к памяти, на которую указывает указатель.
Заключение
«Как использовать Valgrind c++» реализовано на терминале Linux. Он включает в себя основную концепцию, типы Valgrind, его установку, инструкции по использованию и некоторые основные функции его компонентов.Memcheck, как основной компонент Valgrind, обнаруживает ошибку в программе, будь то утечка памяти или неинициализированная память. Все упомянутые примеры показывают работу Valgrind, включая malloc(). Эта статья будет полезна в отношении работы и принципов Valgrind в среде программирования C++.
Об авторе
Акса Ясин
Я целеустремленный профессионал в области информационных технологий и обожаю писать. Я технический писатель и люблю писать для всех разновидностей Linux и Windows.
Алекс Аллен
Примечание. Valgrind предназначен только для Linux. Если вы не используете Linux или вам нужен инструмент, изначально разработанный для облегчения отладки ошибок сегментации и проблем с памятью, попробуйте Cee Studio, полностью онлайн-среду разработки C и C++ от нашего спонсора. Cee Studio предоставляет мгновенные и информативные отзывы о проблемах с памятью.
Valgrind – это многоцелевой инструмент профилирования кода и отладки памяти для Linux на архитектурах x86 и, начиная с версии 3, AMD64. Это позволяет вам запускать вашу программу в собственной среде Valgrind, которая отслеживает использование памяти, например вызовы malloc и free (или new и delete в C++). Если вы используете неинициализированную память, списываете конец массива или забываете освободить указатель, Valgrind может это обнаружить. Поскольку это очень распространенные проблемы, в этом руководстве основное внимание будет уделено использованию Valgrind для поиска этих типов простых проблем с памятью, хотя Valgrind — это инструмент, который может делать гораздо больше.
Кроме того, для пользователей Windows, которые хотят разрабатывать специальное программное обеспечение для Windows, может быть интересен Purify от IBM, который имеет функции, аналогичные Valgrind, для обнаружения утечек памяти и недопустимых обращений к памяти. Доступна пробная загрузка.
Получение Valgrind
Если вы используете Linux и у вас еще нет копии, вы можете скачать Valgrind со страницы загрузки Valgrind.
Установка должна быть такой же простой, как распаковка и распаковка с помощью bzip2 (XYZ — это номер версии в приведенных ниже примерах), который создаст каталог с именем valgrind-XYZ; перейдите в этот каталог и запустите Теперь, когда у вас установлен Valgrind, давайте посмотрим, как его использовать.
Поиск утечек памяти с помощью Valgrind
Утечки памяти являются одними из наиболее сложных для обнаружения ошибок, поскольку они не вызывают никаких внешних проблем до тех пор, пока у вас не закончится память и ваш вызов malloc внезапно не завершится сбоем. На самом деле, при работе с такими языками, как C или C++, в которых нет сборки мусора, почти половина вашего времени может быть потрачена на правильное освобождение памяти. И даже одна ошибка может стоить дорого, если ваша программа работает достаточно долго и следует этой ветке кода.
При запуске кода вам нужно указать инструмент, который вы хотите использовать; просто запустив valgrind, вы получите текущий список. В этом руководстве мы сосредоточимся в основном на инструменте memcheck, поскольку запуск valgrind с инструментом memcheck позволит нам проверить правильность использования памяти. Без каких-либо других аргументов Valgrind представляет сводку вызовов free и malloc: (Обратите внимание, что 18490 — это идентификатор процесса в моей системе; он будет различаться между запусками.) Если у вас есть утечка памяти, то количество alloc и число количество свободных мест будет отличаться (вы не можете использовать одно свободное для освобождения памяти, принадлежащей более чем одному распределению). Мы вернемся к сводке ошибок позже, а пока обратите внимание, что некоторые ошибки могут быть подавлены, потому что некоторые ошибки будут вызваны стандартными библиотечными процедурами, а не вашим собственным кодом.
Если количество распределений отличается от количества освобождений, вам нужно перезапустить программу еще раз с опцией проверки на утечку. Это покажет вам все вызовы malloc/new/etc, для которых нет соответствующего free.
Для демонстрационных целей я буду использовать очень простую программу, которую я скомпилирую в исполняемый файл с именем "example1". В результате появится некоторая информация о программе, завершающаяся списком вызовов malloc, которые не выполнялись. есть последующие вызовы free: это не говорит нам столько, сколько нам хотелось бы — мы знаем, что утечка памяти была вызвана вызовом malloc в main, но у нас нет номера строки. Проблема в том, что мы не компилировали с использованием параметра -g gcc, который добавляет символы отладки. Итак, если мы перекомпилируем с отладочными символами, мы получим следующий, более полезный вывод: Теперь мы знаем точную строку, где была выделена потерянная память. Хотя это все еще вопрос отслеживания того, когда именно вы хотите освободить эту память, по крайней мере, вы знаете, с чего начать поиск. А поскольку для каждого вызова malloc или new у вас должен быть план обращения с памятью, знание того, где теряется память, поможет вам понять, с чего начать поиск.
В некоторых случаях параметр --leak-check=yes не приведет к отображению всех утечек памяти.Чтобы найти абсолютно каждый непарный вызов бесплатного или нового, вам нужно будет использовать параметр --show-reachable=yes. Его вывод почти такой же, но он покажет больше незанятой памяти.
Поиск недопустимого использования указателя с помощью Valgrind
Valgrind также может обнаружить использование недействительной динамической памяти с помощью инструмента memcheck. Например, если вы выделяете массив с помощью malloc или new, а затем пытаетесь получить доступ к расположению за концом массива: Valgrind обнаружит это. Например, запуск следующей программы, example2, через Valgrind приводит к следующему предупреждению. Это говорит нам о том, что мы используем выделенную указателем комнату для 10 байтов, за пределами этого диапазона - следовательно, у нас есть «Недопустимая запись». . Если бы мы попытались прочитать из этой памяти, мы бы получили предупреждение о «Недопустимом чтении размера X», где X — это объем памяти, который мы пытаемся прочитать. (Для char это будет 1, а для int — 2 или 4, в зависимости от вашей системы.) Как обычно, Valgrind печатает трассировку стека вызовов функций, чтобы мы точно знали, где возникает ошибка. .
Обнаружение использования неинициализированных переменных
Еще один тип операции, которую Valgrind обнаружит, — это использование неинициализированного значения в условном выражении. Хотя у вас должна быть привычка инициализировать все переменные, которые вы создаете, Valgrind поможет найти те случаи, когда вы этого не сделаете. Например, запуск следующего кода как example3 через Valgrind приведет к тому, что Valgrind достаточно умен, чтобы знать, что если переменной присваивается значение неинициализированной переменной, эта переменная все еще находится в «неинициализированном» состоянии. Например, запуск следующего кода: в Valgrind as example4 приводит к следующему предупреждению: Вы можете подумать, что проблема была в foo и что остальная часть стека вызовов, вероятно, не так важна. Но так как main передает неинициализированное значение в foo (мы никогда не присваиваем значение y), оказывается, что именно отсюда мы должны начать поиск и проследить путь присвоения переменной, пока не найдем переменную, которая не была инициализирована.
Это поможет вам только в том случае, если вы действительно протестируете эту ветвь кода и, в частности, этот условный оператор. Убедитесь, что вы охватили все пути выполнения во время тестирования!
Что еще найдет Valgrind
Valgrind обнаружит несколько других случаев неправильного использования памяти: если вы дважды вызовете free для одного и того же значения указателя, Valgrind обнаружит это за вас; вы получите сообщение об ошибке: вместе с соответствующей трассировкой стека.
Valgrind также обнаруживает неправильно выбранные методы освобождения памяти. Например, в C++ есть три основных варианта освобождения динамической памяти: free, delete и delete[]. Функция free должна сопоставляться только с вызовом malloc, а не с вызовом, скажем, удаления — в некоторых системах вы можете обойтись без этого, но это не очень переносимо. Более того, ключевое слово delete должно сочетаться только с ключевым словом new (для выделения отдельных объектов), а ключевое слово delete[] должно сочетаться только с ключевым словом new[] (для выделения массивов). (Хотя некоторые компиляторы позволят вам обойтись без неправильной версии удаления, нет гарантии, что это сделают все. Это просто не является частью стандарта.)
Если вы вызовете одну из этих проблем, вы получите эту ошибку: ее действительно нужно исправить, даже если ваш код работает.
Что не найдет Valgrind?
Valgrind не выполняет проверку границ статических массивов (размещенных в стеке). Итак, если вы объявите массив внутри своей функции: тогда Valgrind не предупредит вас! Одним из возможных решений для целей тестирования является простое преобразование ваших статических массивов в динамически выделяемую память, взятую из кучи, где вы получите проверку границ, хотя это может быть беспорядок из-за неосвобожденной памяти.
Еще несколько предостережений
В чем недостаток Valgrind? Он будет потреблять больше памяти — в два раза больше, чем обычно делает ваша программа. Если вы тестируете абсолютно огромный объем памяти, у вас могут возникнуть проблемы. Также потребуется больше времени для запуска вашего кода, если вы используете Valgrind для его тестирования. Это не должно быть проблемой в большинстве случаев, и это влияет только на вас во время тестирования. Но если вы уже запускаете медленную программу, это может повлиять на вас.
Наконец, Valgrind не будет обнаруживать каждую вашу ошибку — если вы не проверите переполнение буфера с помощью длинных входных строк, Valgrind не сообщит вам, что ваш код может перезаписывать память, которую он не должно касаться. Valgrind, как и другой инструмент, нужно использовать с умом, чтобы выявлять проблемы.
Обзор
Valgrind – это инструмент для архитектур x86 и AMD64, который в настоящее время работает под управлением Linux.Valgrind позволяет программисту запускать исполняемый файл в своей собственной среде, в которой он проверяет наличие непарных вызовов malloc и других видов использования недопустимой памяти (например, инициализированной памяти) или недопустимых операций с памятью (таких как двойное освобождение блока памяти или вызов неправильной памяти). функция удаления). Valgrind не проверяет использование статически выделенных массивов.
Читайте также: