По моему опыту, хорошее правило при работе с valgrind - сначала проверить несколько ошибок, попытаться исправить их и снова перезапустить приложение под valgrind. Причина: предположим, у вас есть ошибка в функции, которая выделяет массив и вызывает другую функцию с массивом и размером массива + 1 (т.е. размер на один элемент больше реального размера) em >. Затем, когда следующая функция попытается получить доступ к этому избыточному элементу, valgrind может заметить это и вызвать предупреждение. Но функция может вызвать другую функцию, которая также может попытаться получить доступ к элементу, что также приведет к предупреждению и так далее.
Таким образом, вы получаете кучу сообщений, которые приводят к единственной ошибке. И даже если есть сообщения о другой ошибке, найти их обычно бывает так сложно, что легче исправить первую ошибку и снова перезапустить приложение и valgrind.
Также вам нужно относиться к ошибкам valgrind с долей скептицизма. Например. Я помню, как он однажды сообщил мне о неинициализированной переменной в функции main - по какой-то причине valgrind не мог понять, что это действительно так. Это привело к сообщению об использовании неинициализированной переменной в каждой функции, которую вызывает main, то есть в каждой функции в моей программе. Но я должен упомянуть, что это было давно - три года назад - и я могу предположить, что valgrind не была последней версией даже тогда только потому, что в репозитории Ubuntu, как правило, нет последних версий многих приложений.
Invalid read of size 4
означает где-то переполнение буфера. Трассировка стека первой такой ошибки должна указать, где вы можете найти проблему. Трудно сказать больше, поскольку вы не показывали трассировку стека, но вы должны знать, что функция с ошибкой может быть жертвой неправильного массива сверху.
В качестве примечания я бы посоветовал вам отлаживать такие ошибки с помощью AddressSanitizer, который по умолчанию доступен как для GCC, так и для Clang (и у них есть одинаковые параметры для его включения). Он имеет тенденцию давать гораздо более подробный вывод об ошибке (ура, он даже красочный! Ε :), и по умолчанию закрывает приложение при любой ошибке памяти произошел. Более того, valgrind пропускает большинство ошибок памяти, когда AddressSanitizer этого не делает - например, переполнение стека и т. Д. Да, иногда (как в вашем случае) это работает, но по моему опыту не очень довольно часто.
person
Hi-Angel
schedule
28.06.2015