当前位置:网站首页>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
边栏推荐
- 2022.7.7-----leetcode. six hundred and forty-eight
- Go learning notes (2) basic types and statements (1)
- 快速回复二极管整流特性
- ROS from entry to mastery (IX) initial experience of visual simulation: turtlebot3
- Usage of limit and offset (Reprint)
- Aitm3.0005 smoke toxicity test
- FFA与ICGA造影
- Chisel tutorial - 03 Combinatorial logic in chisel (chisel3 cheat sheet is attached at the end)
- Sqlite数据库存储目录结构邻接表的实现2-目录树的构建
- 10 schemes to ensure interface data security
猜你喜欢

35岁那年,我做了一个面临失业的决定

Chisel tutorial - 03 Combinatorial logic in chisel (chisel3 cheat sheet is attached at the end)

蓝桥ROS中使用fishros一键安装
![[programming questions] [scratch Level 2] March 2019 garbage classification](/img/08/9f7ebf4302c9239784751b579c9efc.png)
[programming questions] [scratch Level 2] March 2019 garbage classification

【編程題】【Scratch二級】2019.12 飛翔的小鳥

Go learning notes (2) basic types and statements (1)

Archery installation test

Go learning notes (1) environment installation and hello world

【编程题】【Scratch二级】2019.03 垃圾分类

35岁真就成了职业危机?不,我的技术在积累,我还越吃越香了
随机推荐
SQL 使用in关键字查询多个字段
正畸注意事项(持续更新中)
95. (cesium chapter) cesium dynamic monomer-3d building (building)
【编程题】【Scratch二级】2019.09 绘制雪花图案
Database query - what is the highest data?
机器人(自动化)等专业课程创新的结果
2022-07-07:原本数组中都是大于0、小于等于k的数字,是一个单调不减的数组, 其中可能有相等的数字,总体趋势是递增的。 但是其中有些位置的数被替换成了0,我们需要求出所有的把0替换的方案数量:
快速上手使用本地测试工具postman
Automated testing: robot framework is a practical skill that 90% of people want to know
【推荐系统基础】正负样本采样和构造
C language 005: common examples
PostGIS learning
FFA与ICGA造影
Linkedblockingqueue source code analysis - add and delete
AWS AWS help error
Is it safe to buy funds online?
Handwriting a simulated reentrantlock
The difference between -s and -d when downloading packages using NPM
Tools for debugging makefiles - tool for debugging makefiles
Teach you to make a custom form label by hand