【问题标题】:delete[] in destructor and passing class object to function as parameter析构函数中的 delete[] 并将类对象作为参数传递给函数
【发布时间】:2013-12-30 01:30:46
【问题描述】:

我有一个用于加载和存储(然后删除)图像数据(像素和标题)的类。在构造函数中,我像这样初始化数据和位图标题:

IMAGE_DATA::IMAGE_DATA():data(0)
{
    memset(&fileheader,0,(sizeof(BITMAPFILEHEADER)));
    memset(&infoheader,0,(sizeof(BITMAPINFOHEADER)));
};

data 是一个unsigned char* 数组,在加载函数中分配有new[...]。 析构函数:

IMAGE_DATA::~IMAGE_DATA()
{
    freeData();
};

void IMAGE_DATA::freeData()
{
    delete[] data;

    memset (&fileheader, 0, sizeof(fileheader));
    memset (&infoheader, 0, sizeof(infoheader));
};

现在的问题是,在过滤类中,我将加载数据后的类对象作为参数传递:

IMAGE_DATA image;

image.load("filename"); //load headers and pixel data

FILTER filter;

filter.scale(image,scalefactor,"outputfilename");  //scales the image and write to a .bmp

这是我的代码的缩短版本。所以,IMAGE_DATA ::load 运行顺利,但是当代码到达缩放函数时,我得到以下断言失败:

Debug Assertion Failed!
....
Expression:
_BLOCK_TYPE_IS_VALID(pHeap->nBlockUse)
....

crt\src\dbgdel.cpp第 52 行。

这发生在我创建了析构函数之后。出于好奇,我更改了参数,因此我将它们作为参考传递。

/*FILTER::*/scale(IMAGE_DATA& /*passed as reference*/, unsigned short, const char*); 

现在可以了。如果我通过“按值”传递,似乎调用了析构函数,但构造函数也应该调用,并且应该没有问题,因为在构造函数中我初始化了所有内容。

我想通过值传递它,因为我想保持原始不变,我只想使用它的数据。

如何在不作为参考传递的情况下使其工作,以及它与按值传递有何不同,因为按值传递似乎更“安全”。

编辑:我刚刚找到了一篇关于此的帖子:Side effects when passing objects to function in C++(我似乎没有使用正确的关键字进行搜索)所以从这篇文章中我读过我应该做一个复制构造函数和赋值运算符。

【问题讨论】:

    标签: c++ memory-management c++11 destructor pass-by-value


    【解决方案1】:

    在 C++ 中,有一个“三原则”,基本上是说,如果你有一个自定义析构函数,你也很可能应该创建一个复制构造函数和一个复制赋值运算符。

    您假设在“按值传递”时调用构造函数是正确的 - 但是,这是复制构造函数,而不是您提供的默认构造函数。

    如果您没有定义一个,编译器会很乐意为您提供一个 - 但它会对您拥有的所有指针进行“浅”复制 - 本质上,您的副本将指向与原始内存相同的内存。我想你可以理解为什么它会删除你原来的:)

    【讨论】:

    • hm 我刚刚找到一篇关于此的帖子:D,我将阅读关于三规则的内容,感谢您的提示 +1。我会在 7 分钟内接受这个
    • 而在 C++11 中,“三规则”已扩展为“五规则”——引入了rvalue references,还有一个move constructor 和一个move assignment operator你也应该实施。这体现了您通常应该避免将成员声明为原始指针并使用智能包装器并让它们为您处理复制/移动/销毁语义的概念。
    猜你喜欢
    • 1970-01-01
    • 2013-12-12
    • 1970-01-01
    • 2016-04-21
    • 2015-11-22
    • 2021-04-13
    • 2021-03-20
    • 2012-02-27
    • 2017-06-04
    相关资源
    最近更新 更多