Утечка памяти, вызванная списком инициализаторов? - PullRequest
0 голосов
/ 24 января 2020

У меня утечки памяти в моем коде, согласно valgrind, все они происходят из конструктора в моем классе; вот его код:

  School::School(unsigned int NumberOfClasses[]) :
        first(*new Grade<Student, std::equal_to<Student>>(NumberOfClasses[0])),
        second(*new Grade<Student, std::equal_to<Student>>(NumberOfClasses[1])),
        third(*new Grade<Student, std::equal_to<Student>>(NumberOfClasses[2])) {

}

Grade - специальный шаблон массива, который я создал, который получает как элемент (в данном случае, Student), так и функцию сравнения для элемента (который я также предоставил); у него есть и конструктор, и деструктор, который работает без утечек памяти. Вот подпись конструктора:

Grade<Element, Compare> :: Grade(unsigned int size);

Так как в моей школе 3 класса, его деструктор =default;

Это то, что я получаю от valgrind:

    8 bytes in 1 blocks are indirectly lost in loss record 1 of 6
==21426==    at 0x4C2A888: operator new[](unsigned long) (vg_replace_malloc.c:423)
==21426==    by 0x4041B8: Grade<BmbSchool::Student, std::equal_to<BmbSchool::Student> >::Grade(unsigned int) (GradeImp.h:9)
==21426==    by 0x40298B: BmbSchool::School::Grade(unsigned int*) (School.cpp:27)
==21426==    by 0x405B6C: main (BmbSchool.cpp:148)

Другой тип ошибки, которую я получаю, довольно похожий:

==21426== 32 (24 direct, 8 indirect) bytes in 1 blocks are definitely lost in loss record 3 of 6
==21426==    at 0x4C2A1E3: operator new(unsigned long) (vg_replace_malloc.c:334)
==21426==    by 0x402974: BmbSchool::School::Grade(unsigned int*) (School.cpp:28)
==21426==    by 0x405B6C: main (BmbSchool.cpp:148)

В любом случае это имеет смысл? Как я могу решить это? Я могу предположить, что не будет никаких исключений bad_allo c, генерируемых при определении массивов.

изменить: определение для школы -

    Grade<Student, std::equal_to<Student>> first;
    Grade<Student, std::equal_to<Student>> second;
    Grade<Student, std::equal_to<Student>> third;

Ответы [ 2 ]

1 голос
/ 24 января 2020

Утечка в вашем неправильном использовании new. Вы динамически распределяете 3 Grade объекта, но затем разыменовываете указатели, чтобы передать эти объекты конструктору копирования ваших трех членов данных. Вы никогда не delete объекты, которые вы new ', следовательно, протекает.

Вам не нужно вообще использовать new в этой ситуации. Просто передайте свои входные значения непосредственно в тот же конструктор самих членов данных, которые вы вызывали с new:

School::School(unsigned int NumberOfClasses[]) :
    first(NumberOfClasses[0]),
    second(NumberOfClasses[1]),
    third(NumberOfClasses[2])
{
}
0 голосов
/ 25 января 2020

Если вы можете использовать C ++ 11 или более позднюю версию, вы можете использовать std :: array, что-то вроде

 School::School(const std::array<unsigned int, 3>& NumberOfClasses) :
 // as Remy Lebeau's answer

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

...