当有大量内存分配时,如何处理C++编程中的异常
How to deal with Exceptions in C++ programming when there are a lot of memory allocation
我是C++程序领域的新手,我读了《更有效C++》一书。有一个关于如何处理C++异常的特定部分。就第 10 项而言,作者声称我们应该避免构造函数中的内存泄漏,如以下示例所示。
BookEntry::BookEntry(const string& name, const string& address,
const string& imageFileName,
const string& audioClipFileNmae):theName(name), theAddress(address),
theImage(0), theAudioClip(0) {
try {
if (imageFileName != "") {
theImage = new Image(imageFileName);
}
if (audioClipFileName != "") {
theAudioClip = new AudioClip(audioClipFileName);
}
}
catch (...) {
delete theImage;
delete theAudioClip;
}
这样,当创建图像或音频剪辑时出现错误时,我们可以避免源泄漏。我的问题是,如果有很多函数包含内存分配,如下所示。
void BookEntry::test1() {
float *A = new float[1000];
float *B = new float[1000];
....
delete [] A;
delete [] B;
}
我是否必须使用 try catch 结构来处理内存泄漏的危险?通常,我更喜欢只测试指针 A 和指针 B 是否为空指针,如果分配失败,我将立即中止程序。
你可能误解了这本书所说的"内存泄漏"是什么意思。分配失败可能是内存泄漏的最终结果,但这两件事并不相同。
这本书所讨论的是如果构造函数失败会发生什么AudioClip
。不是AudioClip
的内存分配,而是AudioClip
的构造函数。因为请记住,构造函数只有一种方法来发出失败信号:引发异常。
如果它引发,并且BookEntry
构造函数调用的调用堆栈中的某人捕获了该异常,则以前分配的theImage
将永远不会被清理。BookEntry
的构造函数从未成功完成,因此永远不会调用其析构函数(因为该对象从未存在过,因此无法删除它(。
这就是为什么现在(又名:C++11 后(,我们会将这些分配的成员存储在智能指针中。虽然永远不会调用BookEntry
的析构函数,但将调用其任何成功构造的子对象的析构函数。因此,如果theImage
是一个unique_ptr<Image>
,它将调用其析构函数,这将删除它所持有的Image
。
通常,我更喜欢只测试指针 A 和指针 B 是否为空指针,如果分配失败,我将立即中止程序。
然后,内存分配失败的异常对您来说甚至更好,因为您不必测试任何内容。您只需让分配失败异常到达main
,您的程序就会终止。
但是,上述问题与分配失败异常无关。
- 警告处理为错误这里有什么问题
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 使用流处理接收到的数据
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 基于多个条件处理地图中的所有元素
- 如何用数字处理log(0)
- SSL上的`curl_easy_send`和`curl_asy_recv`:如何处理`CURLE_AGAIN`
- 错误处理.将系统错误代码映射到泛型
- 从文本文件中读取时钟时间和事件时间并进行处理
- 在运行时处理类型擦除的数据-如何不重新发明轮子
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 用于矢量处理的多个线程
- 对字符串进行排序时,在c++中处理sort()
- 如何处理linux终端中带有负号(-)的C++中的命令行参数
- 处理除以零会导致<csignal>意外行为
- 是否可以在c++中处理字符串流中的各个元素
- 在多个核心中处理一个HTTP请求