Утечка памяти в классе C ++? - PullRequest
0 голосов
/ 16 сентября 2018

Мне было интересно, будет ли класс, созданный мной для программы, утекать память.

Вот моя реализация,

BubbleSort.h имеет 3 приватные переменные:

int arrSize = Array Size
int* intArray = Original Array
int* narr = Bubble Sorted Array

BubbleSort.cpp

#include "BubbleSort.h"

BubbleSort::BubbleSort(int size, int* arr)
{
    arrSize = size;
    intArray = arr;
    printf("BubbleSort();\n");
}


// Object Destruction
BubbleSort::~BubbleSort()
{
    free(narr);
}

int* BubbleSort::Sort() {
    int swap = 0;
    narr = (int*)malloc(arrSize * sizeof(int));

    for (int i = 0; i < arrSize; i++) {
        narr[i] = intArray[i];
    }

    for (int i = 0; i < arrSize - 1; i++) {
        for (int j = (i + 1); j < arrSize; j++) {
            if (narr[j] < narr[i]) {
                swap = narr[i];
                narr[i] = narr[j];
                narr[j] = swap;
            }
        }
    }
    return narr;
}

А вот мой основной файл

#include "main.h"
#include "classes.h"

int main(int argc, char* argv[]) {
    const int size = 10;
    int arr[size] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};

    BubbleSort sort = BubbleSort::BubbleSort(size, arr);

    int* narr = sort.Sort();

    for (int i = 0; i < size; i++) {
        printf("%d > %d\n", arr[i], narr[i]);
    }

    printf("Hello World.\n");
    getchar();
}

Будет ли эта программа пропускать память во время работы?

Когда я запускал код, я проверял, чтоЭкземпляр BubbleSort 'sort' разрушал, но это было только тогда, когда приложение завершило работу.В настоящее время я учусь использовать malloc() и free() в моем курсе программирования, и у меня было немного свободного времени, поэтому я решил создать класс Bubble Sort и хотел поэкспериментировать с ним!Поэтому я надеюсь, что в коде не так много ошибок (связанных с использованием указателей).

Ответы [ 2 ]

0 голосов
/ 16 сентября 2018

Вы не должны использовать malloc и free, если вы не взаимодействуете с кодом C. Старайтесь также избегать new и delete, поскольку в C ++ есть много более простых шаблонов, которые гарантированно не пропускают и работают так же быстро. Подумайте о std::vector и, если vector не достаточно хорош, подумайте о std::unique_ptr<int[]> narr с std::make_unique<int[]>(size).

Ваша программа не протекает и не падает по чистой случайности. Чтобы избежать утечек, у вашего класса должен быть четкий инвариант относительно памяти, а у него его нет. Невозможно узнать, когда narr имеет недопустимый указатель или когда он указывает на память, которая должна быть освобождена. В результате следующие утечки:

int arr1[size] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
BubbleSort sort = BubbleSort::BubbleSort(size, arr1);
int* narr = sort.Sort();
narr = sort.Sort();

И следующее имеет неопределенное поведение (бесплатно по неинициализированному указателю):

int arr1[size] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
BubbleSort sort = BubbleSort::BubbleSort(size, arr1);
return 0;

Самый простой способ (и правильный в 99,9% случаев) справиться с этим - определить собственника. Вы решаете заранее, кому принадлежит какой объект. С std::vector и std::unique_ptr язык решает это за вас. Язык не позволяет случайно передать право собственности на std::unique_ptr без явного действия с вашей стороны. Если вы допустили ошибку, компилятор просто выдаст вам ошибку.


Примечание : если вы хотите изучать C ++, то, когда вы выходите из фона C, может быть проще начать с malloc, free, printf и необработанных указателей повсюду. Однако вы должны помнить, что это не идиоматический C ++. Рано или поздно вы должны перейти на идиомы C ++, такие как RAII, классы с явным владением и инвариантом, и использовать библиотеку C ++ вместо C.
0 голосов
/ 16 сентября 2018

Эта схема распределения очень плохая. Да, программа, которую вы дали, не просачивается, но вы утечете в больших программах, если не переосмыслите свои шаблоны.

Либо выделяйте narr только в конструкторе (RAII), либо не освобождайте в деструкторе, но в вызывающей функции (старая школа), либо вообще избавьтесь от объекта и передайте size и arr в sort().

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

Как указал Сэм Варшавик, если вы создадите один из них и не будете называть сортировку, вы попадете в деструктор. Любой из предложенных мною методов это исправит, как и инициализация narr в NULL в конструкторе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...