2015-11-11 3 views
3

с использованием ответов от operator overloading memory leak Я добавил конструктор копирования и оператор копирования, изменил оператор +(), как сообщал NathanOliver, и теперь я перехожу к конструктору статического массива. Все еще есть утечка памяти, и странно, что я получил эту утечку памяти, даже если в основном есть только инициализация переменной класса, не имеет значения, с параметрами или нет. Любые предложения? Я думаю, что cunstructor действителен.утечка памяти при создании переменной класса

Set::Set(int n, int* array){ 
    number = n; 
    elems = array; 
    std::sort(elems, elems + number); 
} 

Set::Set(const Set& s){ 
    number=s.number; 
    elems=s.elems; 
} 
Set& operator=(const Set& X){ 

    if(this==&X) 
    return *this; 
    delete [] elems; 
    elems=X.elems; 
    number=X.number; 
    return *this; 

Я использую gcc (tdm64-2) 4.8.1 компилятор.

+1

elems = X.elems просто копирует указатель, это то, что вы хотите? – KostasRim

+0

Ваш код не обнаруживает утечки памяти, потому что вы не выделяете какую-либо динамическую память в показанном коде. Чтобы найти утечки, найдите код, который выделяет, а затем следуйте указателям. – user2079303

ответ

4

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

Set::Set(int n, int* array){ 
    number = n; 
    elems = array; 
    std::sort(elems, elems + number); 
} 

Этот конструктор принимает массив. Если этот массив выделен в куче, используя новый, то он должен быть освобожден, используя delete []. Теперь заявление:

elems = array; 

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

Теперь то же самое здесь:

Set& operator=(const Set& X){ 

    if(this==&X) 
    return *this; 
    delete [] elems; 
    elems=X.elems; 
    number=X.number; 
    return *this; 
} 

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

delete[] elems; 
elems = new int[n]; //where n is x.elems length 
//use memcpy() function or a for loop to copy the values of x.elems 

Наконец, добавьте класс деструктор в класс:

~Set() { 
    if(elems != nullptr) //check for empty array 
     delete[] elems; 
} 

иметь в виду Бьерн Страуструп создатель C++ говорит, что вы должны следовать RIII (так называемый R тройные I). В основном, когда вы создаете класс, всегда используйте new in constructor и delete в деструкторе. Избегайте новых/удалить любую другую функцию. Передающие указатели могут быть сложными.

+0

, но как вы объясняете утечку памяти во время такого действия в основном, как 'Set a (5, ar1)' где ar1 - статическая таблица размером 5? – Saris

+0

причина ar1 статична, она сохраняется там, где другие статические объекты (в стеке), а затем при использовании оператора присваивания перегрузки и вы удаляете это статическое хранилище ... Когда вы используете новую операцию, она должна быть сопряжена с удалением позже. Другие вопросы ? – KostasRim

+0

@ KostasRim вы перепутали «утечку памяти» и «висящий указатель». – user2079303

Смежные вопросы