当前位置:网站首页>If an exception is thrown in the constructor, the best way is to prevent memory leakage?
If an exception is thrown in the constructor, the best way is to prevent memory leakage?
2022-07-08 00:10:00 【Big mulberry security team】
If an exception is thrown in the constructor , Destructors will not be called ( Simple class , No inheritance ). therefore , If an exception is thrown in the constructor , And there are some chances that the heap memory has not been cleared . So what's the best thing to do here ?
If you avoid “ bare ” resources ( Such as bare pointer , Bare mutexes, etc ), And include all the contents in the appropriate RAII Behavior in a container or class , So even if there are exceptions , There will be no problem as you described .
in other words , Do not get raw resources in the constructor . Instead, create one that follows itself RAII Instance of the object . such , Even if your constructor fails ( That is, create the constructor of the instance ), The destructor of the initialization object will be called .
therefore , It's not a good idea :
#include<iostream>
#include<stdexcept>
struct Bad {
Bad() {
double *x = new double;
throw(std::runtime_error("the exception was thrown"));
}
~Bad() {
delete x;
std::cout<<"My destructor was called"<<std::endl;
}
double *x;
};
int main() {
try {
Bad bad;
} catch (const std::exception &e) {
std::cout<<"We have a leak! Let's keep going!"<<std::endl;
}
std::cout<<"Here I am... with a leak..."<<std::endl;
return 0;
}
Output :
We have a leak! Let's keep going!
Here I am... with a leak...
An example of correction :
#include<iostream>
#include<stdexcept>
struct Resource {
Resource() {
std::cout<<"Resource acquired"<<std::endl;
}
~Resource() {
std::cout<<"Resource cleaned up"<<std::endl;
}
};
struct Good {
Good() {
std::cout<<"Acquiring resource"<<std::endl;
Resource r;
throw(std::runtime_error("the exception was thrown"));
}
~Good() {
std::cout<<"My destructor was called"<<std::endl;
}
};
int main() {
try {
Good good;
} catch (const std::exception &e) {
std::cout<<"We DO NOT have a leak! Let's keep going!"<<std::endl;
}
std::cout<<"Here I am... without a leak..."<<std::endl;
return 0;
}
Output :
Acquiring resource
Resource acquired
Resource cleaned up
We DO NOT have a leak! Let's keep going!
Here I am... without a leak...
My opinion is as follows : Try to encapsulate all resources that need to be liberated into classes that the constructor does not throw , Destructors correctly release resources . then , In other classes that the destructor may throw , Just create an instance of the wrapper resource , And it will ensure that the destructor of the obtained resource wrapper will be cleaned up .
The following may be a better example :
#include<mutex>
#include<iostream>
#include<stdexcept>
// a program-wIDe mutex
std::mutex TheMutex;
struct Bad {
Bad() {
std::cout<<"Attempting to get the mutex"<<std::endl;
TheMutex.lock();
std::cout<<"Got it! I'll give it to you in a second..."<<std::endl;
throw(std::runtime_error("Ooops,I threw!"));
// will never get here...
TheMutex.unlock();
std::cout<<"There you go! I released the mutex!"<<std::endl;
}
};
struct ScopedLock {
ScopedLock(std::mutex& mutex)
:m_mutex(&mutex) {
std::cout<<"Attempting to get the mutex"<<std::endl;
m_mutex->lock();
std::cout<<"Got it! I'll give it to you in a second..."<<std::endl;
}
~ScopedLock() {
m_mutex->unlock();
std::cout<<"There you go! I released the mutex!"<<std::endl;
}
std::mutex* m_mutex;
};
struct Good {
Good() {
ScopedLock autorelease(TheMutex);
throw(std::runtime_error("Ooops,I threw!"));
// will never get here
}
};
int main() {
std::cout<<"Create a Good instance"<<std::endl;
try {
Good g;
} catch (const std::exception& e) {
std::cout<<e.what()<<std::endl;
}
std::cout<<"Now,let's create a Bad instance"<<std::endl;
try {
Bad b;
} catch (const std::exception& e) {
std::cout<<e.what()<<std::endl;
}
std::cout<<"Now,let's create a whatever instance"<<std::endl;
try {
Good g;
} catch (const std::exception& e) {
std::cout<<e.what()<<std::endl;
}
std::cout<<"I am here despite the deadlock..."<<std::endl;
return 0;
}
Output ( use gcc 4.8.1 compile , Use -std = c 11):
Create a Good instance
Attempting to get the mutex
Got it! I'll give it to you in a second...
There you go! I released the mutex!
Ooops,I threw!
Now,let's create a Bad instance
Attempting to get the mutex
Got it! I'll give it to you in a second...
Ooops,let's create a whatever instance
Attempting to get the mutex
边栏推荐
- Rectification characteristics of fast recovery diode
- Magic fast power
- Relevant methods of sorting arrays in JS (if you want to understand arrays, it's enough to read this article)
- Chisel tutorial - 04 Control flow in chisel
- 串联二极管,提高耐压
- SQL 使用in关键字查询多个字段
- 光流传感器初步测试:GL9306
- Traduction gratuite en un clic de plus de 300 pages de documents PDF
- How does starfish OS enable the value of SFO in the fourth phase of SFO destruction?
- 【编程题】【Scratch二级】2019.09 制作蝙蝠冲关游戏
猜你喜欢
BSS 7230 flame retardant performance test of aviation interior materials
80%的人答错,苹果logo上的叶子到底朝左还是朝右?
Binary sort tree [BST] - create, find, delete, output
机器人(自动化)等专业课程创新的结果
某马旅游网站开发(登录注册退出功能的实现)
CoinDesk评波场去中心化进程:让人们看到互联网的未来
DataGuard active / standby cleanup archive settings
10 schemes to ensure interface data security
【编程题】【Scratch二级】2019.09 绘制雪花图案
STM32F1与STM32CubeIDE编程实例-旋转编码器驱动
随机推荐
BSS 7230 flame retardant performance test of aviation interior materials
【编程题】【Scratch二级】2019.09 绘制雪花图案
Install sqlserver2019
Chisel tutorial - 02 Chisel environment configuration and implementation and testing of the first chisel module
Basic learning of SQL Server -- creating databases and tables with code
Sqlite数据库存储目录结构邻接表的实现2-目录树的构建
How to measure whether the product is "just needed, high frequency, pain points"
2022.7.7-----leetcode. six hundred and forty-eight
Basic learning of SQL Server -- creating databases and tables with the mouse
Cmake learning notes (1) compile single source programs with cmake
FFA and ICGA angiography
AWS AWS help error
Detailed explanation of interview questions: the history of blood and tears in implementing distributed locks with redis
Gorm Association summary
Daily question brushing record (16)
When creating body middleware, express Is there any difference between setting extended to true and false in urlencoded?
QT creator add JSON based Wizard
Redis caching tool class, worth owning~
Restricted linear table
Chisel tutorial - 04 Control flow in chisel