此C ++类泄漏内存吗?

时间:2018-09-16 03:50:48

标签: c++ memory-management memory-leaks

我想知道我为程序编写的类是否会泄漏内存。

这是我的实现方式,

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(),并且有一些空闲时间,所以我决定制作一个冒泡排序类并想尝试一下!因此,我希望代码中不会出现太多错误(与指针的使用有关)。

2 个答案:

答案 0 :(得分:2)

除非与C代码交互,否则不应使用mallocfree。尽量避免使用newdelete,因为C ++具有许多更简单的模式,可以保证不泄漏而且速度也一样快。想想std::vector,如果vector不够好,请想像std::unique_ptr<int[]> narrstd::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::vectorstd::unique_ptr,语言可以为您决定。如果没有明确的操作,该语言不会让您不慎转移std::unique_ptr的所有权。如果您输入有误,编译器只会给您一个错误。


旁注:如果您想学习C ++,那么当您具有C背景时,从mallocfreeprintf和原始指针无处不在。但是,您应该记住,这不是惯用的C ++。迟早,您必须转而使用RAII之类的C ++习惯用法,这些类具有明确的所有权和不变性,并使用C ++库而不是C。

答案 1 :(得分:1)

此分配模式非常糟糕。是的,您提供的程序不会泄漏,但是如果您不重新考虑模式,您将在更大的程序中泄漏。

要么仅在构造函数(RAII)中分配narr,要么在析构函数中不释放,而在调用函数中(旧派)释放,或者完全摆脱对象并传递size和{ {1}}至arr

很快就会开始使用标准模板库,但这是另一天的话题。

正如Sam Varshavick所指出的那样,如果您创建其中一个is并且不调用sort,则会在析构函数中崩溃。我提供的任何方法都可以解决此问题,就像在构造函数中将sort()初始化为narr一样。