Откуда эта утечка памяти? - PullRequest
0 голосов
/ 21 ноября 2018

В моей реализации ArrayList у меня есть метод для изменения размера массива.Это выглядит так:

template<typename T>
int ArrayList<T>::changeSize(int newsize)
{
    T* tmp = (T*)(T*)realloc(internal_array,sizeof(T)*newsize);
    if(tmp == NULL)
    {
        return 0;
    }
    internal_array=tmp; 
    Capacity = newsize;
    return 1;
}

Эта часть кода вызывает утечку памяти при ее использовании, любая идея, что здесь может быть не так?РЕДАКТИРОВАТЬ: Обработка realloc в NULL все равно не помогла, обновил код и добавил вывод дезинфицирующего средства для адреса:

=================================================================================== == 4615 == ОШИБКА: LeakSanitizer: обнаруженные утечки памяти

Прямая утечка 16 байтов в 1 объекте (ах), выделенная из:

#0 0x7f0c9d1b5f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x557b3b693fb2 in ArrayList<int>::changeSize(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2fb2)
#2 0x557b3b6939c4 in ArrayList<int>::Add(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x29c4)
#3 0x557b3b692671 in readInput(ArrayList<int>*) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x1671)
#4 0x557b3b693339 in main (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2339)
#5 0x7f0c9cd07b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

Прямая утечка 4 байтов в 1 объекте (ах)выделено из:

#0 0x7f0c9d1b5f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x557b3b693fb2 in ArrayList<int>::changeSize(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2fb2)
#2 0x557b3b693e0b in ArrayList<int>::Remove(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2e0b)
#3 0x557b3b692d07 in findMinDistances(ArrayList<int>) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x1d07)
#4 0x557b3b6934a3 in main (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x24a3)
#5 0x7f0c9cd07b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

РЕЗЮМЕ: AddressSanitizer: утечка 20 байтов за 2 выделения.

1 Ответ

0 голосов
/ 21 ноября 2018

Вы неправильно читаете ошибку:

Direct leak of 16 byte(s) in 1 object(s) allocated from:

#0 0x7f0c9d1b5f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x557b3b693fb2 in ArrayList<int>::changeSize(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2fb2)
#2 0x557b3b6939c4 in ArrayList<int>::Add(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x29c4)
#3 0x557b3b692671 in readInput(ArrayList<int>*) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x1671)
#4 0x557b3b693339 in main (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2339)
#5 0x7f0c9cd07b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

Это ясно говорит о том, что память, выделенная на ArrayList<int>::changeSize(int), является утечкой памяти.Он не говорит, какая операция вызвала утечку.

Это означает, что changeSize(int) в порядке.Проблема лежит в другом месте.Необходимо убедиться, что соблюдается правило 5:

  1. Деструктор освобождает память.
  2. Конструктор копирования копирует содержимое internal_array, а не указатель.
  3. Оператор присваивания копирует содержимое, а не указатель.Рассмотрим идиому копирования и замены.
  4. Конструктор Move копирует указатель, но обнуляет другой объект.
  5. Назначение перемещения меняет местами указатели или назначает один указатель и освобождает другой.

Возможно, ошибка связана с отсутствием или ошибкой одного из указанных выше.Хороший способ облегчить обнаружение таких ошибок во время компиляции - это использовать std :: unique_ptr с пользовательским средством удаления вместо освобождения вручную.

Пожалуйста, обратите внимание, что ваш код вылетити / или утечка памяти чем-либо сложным, например, T = vector или T = big num.Вы можете добавить static_assert(std::is_trivial<T>::value);, чтобы убедиться, что он не создан, например, std::map.

...