在我下面介绍的代码中,我遇到了一个问题。它表现为一个bad_alloc异常,这是因为传递给reader ( CompressedBufferReader )的参数是一个错误的字符串。
class FileReader {
FILE *file;
protected:
unsigned char *data; // local copy
long size;
public:
FileReader(const char *filename);
~FileReader();
unsigned long getSize();
unsigned char *getFileData();
};
class CompressedBufferReader {
unsigned char *buffer;
unsigned long len;
public:
CompressedBufferReader(unsigned char *);
~CompressedBufferReader();
unsigned char *getBuffer();
unsigned long getLength();
};
CompressedBufferReader::CompressedBufferReader(unsigned char *srcCompressed) {
len = 0; buffer = 0;
len = GetDecompressedBufferSize(srcCompressed);
buffer = new unsigned char[len]; if (!buffer) throw std::runtime_error("Cannot allocate!");
WriteDecompressedBuffer(buffer, len, srcCompressed);
}
CompressedBufferReader::~CompressedBufferReader() {
delete[] buffer;
}
unsigned char *CompressedBufferReader::getBuffer() {return buffer;}
unsigned long CompressedBufferReader::getLength() {return len;}
// similar interface to FileReader. Does not inherit because it does not benefit from doing so.
class CompressedFileReader {
CompressedBufferReader reader;
public:
CompressedFileReader(const char *filename);
unsigned char *getFileData();
unsigned long getSize();
};
CompressedFileReader::CompressedFileReader(const char *filename) : reader(FileReader(filename).getFileData()){} // this line is causing the problem
unsigned char *CompressedFileReader::getFileData() { return reader.getBuffer(); }
unsigned long CompressedFileReader::getSize() { return reader.getLength(); }更具体地说,我匿名创建的FileReader似乎在其数据内容被传递给reader的构造函数( CompressedBufferReader )之前就被释放了。
问题是我不能以一种允许我正确实例化FileReader的方式来编写CompressedFileReader的构造函数,因为我打算使用CompressedBufferReader的构造函数,这意味着我必须在构造函数的主体之前调用它。有点进退两难。这个问题是如何解决的?
发布于 2011-09-19 04:55:51
我不认为您使用构造函数的方式有问题,这应该会导致bad_alloc (尽管代码看起来确实很笨拙)。让我们看一下导致问题的代码行的执行情况:
CompressedFileReader::CompressedFileReader(const char *filename) :
reader(FileReader(filename).getFileData()){}执行以下步骤:
FileReader。它的构造函数是通过const char*.filename构造函数,因为我们没有它的代码。我假设,它应该将文件读取到分配的缓冲区中,该缓冲区存储在临时FileReader.getFileData()的unsigned char *.reader,成员上,并返回data的值。我假设,这是一个使用FileReader.getFileData()构造的unsigned char *.reader,,它是一个CompressedBufferReader。因此,问题不在于构造的顺序,也不在于临时FileReader的生命周期。有几个未知之处你应该研究一下:
FileReader的构造函数是否创建了有效的缓冲区,并将其存储在FileReader getFileData() GetDecompressedBufferSize()返回有效缓冲区的正确值?WriteDecompressedBuffer抛出?< code >G241
最后,您可能希望简化代码。像这样的结构可读性不是很好。当然,使用像向量这样的标准容器会让它更安全。
发布于 2011-09-19 03:56:44
您的代码违反了一条非常重要的规则,即“三大规则”。
如果你的类有解构函数,赋值运算符或复制构造函数的任何,那么它应该有这三个。
原因是,如果存在自定义析构函数,那么很可能自动合成的赋值操作符和复制构造函数(简单的成员间复制构造或赋值)将不是正确的操作。
这条规则非常重要,如果你碰巧发现有一个析构函数但默认的复制构造函数是有意义的,那么至少在注释中写下,你没有忘记复制构造函数和/或赋值,但自动提供的将是正确的。
相反,如果您的类不能被复制或复制构造,那么通过声明它是私有的并且不编写实现来禁止该操作。
在您的特定情况下,当您的两个类中的任何一个的实例被复制或赋值时,指针将被复制,但随后数据将被销毁两次。
https://stackoverflow.com/questions/7463811
复制相似问题