По словам Валгринда, у меня в программе довольно большая утечка памяти, но на самом деле я не думаю, что это так. А может я просто чего-то не осознаю. Я использую Valgrind впервые, поэтому могу неправильно его интерпретировать или, возможно, воспринимать его слишком серьезно.

В любом случае, Valgrind сообщает мне, что ~ 13 МБ (56 байтов напрямую, остальные косвенные) определенно потеряны. Рассматриваемый код выглядит так:

Node* newRoot = malloc(sizeof(Node));
newRoot->children[0] = tree->root;
newRoot->children[1] = otherNode;
newRoot->k = 2;

tree->root = newRoot;

Как вы, наверное, догадались, у меня есть древовидная структура, в которой объект дерева имеет один корень и несколько дочерних узлов узла. В этой части кода дерево расширяется до вершины; старый корень становится потомком нового узла, который затем становится новым корнем. tree - это Tree*, член root - это указатель узла, а children - это массив указателей узлов.

Теперь Valgrind сообщает мне, что память, выделенная указанным выше malloc, потеряна, но, насколько я понимаю, я указываю на этот блок памяти из нового корня, в то время как старый корень остается дочерним по отношению к новому корню.

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

Я что-то упускаю? Есть ли способ получить более подробную информацию от Valgrind, чтобы узнать, что именно (не) происходит?

1
poke 20 Янв 2014 в 16:17
Может быть, будет полезно показать нам функцию освобождения. Кроме того, какие параметры вы используете для запуска valgrind?
 – 
Kiril Kirov
20 Янв 2014 в 16:20
Можете ли вы предоставить вывод valgrind. Также убедитесь, что в выходных данных valgrind есть различия между definitly lost и maybe lost.
 – 
drahnr
20 Янв 2014 в 16:23
Кто раньше указывал на otherNode и куда указывает этот указатель сейчас?
 – 
Lundin
20 Янв 2014 в 16:26
Вау, не могу поверить, что не подумал об этом раньше. Это действительно была функция освобождения. Пока я с удовольствием спускал дерево к листьям и правильно их освобождал, я совершенно забыл об освобождении самих узлов. И это устранило все утечки памяти - намного проще, чем я ожидал. Спасибо, что заставили меня посмотреть туда! ^^ И все мои сомнения по поводу Валгринда внезапно исчезли.
 – 
poke
20 Янв 2014 в 16:37
- рад быть полезным :). В основном функция memcheck от valgrind контролирует каждое выделение памяти и освобождает ли выделенная память позже. Если он не освобожден, он показывает вам, где он был размещен, поскольку он не может показать вам, где он должен быть освобожден. Вот почему я попросил функцию освобождения.
 – 
Kiril Kirov
20 Янв 2014 в 16:40

1 ответ

Лучший ответ

Что valgrind memcheck (инструмент по умолчанию) в основном делает для мониторинга утечек памяти, так это отслеживает каждое выделение памяти и освобождает ли выделенная память позже. Если он не освобожден, он показывает вам, где он был размещен, поскольку он не может показать вам, где он должен быть освобожден.

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

Еще одна полезная вещь: как вы запускаете valgrind? Использую следующие варианты:

valgrind --trace-children=yes --track-fds=yes --log-fd=2 --error-limit=no \
         --leak-check=full --show-possibly-lost=yes --track-origins=yes \
         --show-reachable=yes executable executable_arguments_if_any

Иногда может быть полезна функция verbose.

5
Kiril Kirov 20 Янв 2014 в 16:45
2
На самом деле я забыл освободить внутренние узлы в своей функции освобождения, поэтому ошибки действительно имели смысл. Это устранило все утечки памяти :) - Я просто использовал --leak-check=yes сейчас, но обязательно проверю и другие варианты. Большое тебе спасибо! :)
 – 
poke
20 Янв 2014 в 16:54