当前位置:网站首页>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
边栏推荐
- Using Google test in QT
- The function is really powerful!
- Uic564-2 Appendix 4 - flame retardant fire test: flame diffusion
- The difference between get and post
- Benchmarking Detection Transfer Learning with Vision Transformers(2021-11)
- Binder核心API
- Basic learning of SQL Server -- creating databases and tables with code
- 串联二极管,提高耐压
- Cmake learning notes (1) compile single source programs with cmake
- Handwriting a simulated reentrantlock
猜你喜欢
The result of innovation in professional courses such as robotics (Automation)
ROS from entry to mastery (IX) initial experience of visual simulation: turtlebot3
Apng2gif solutions to various problems
Chisel tutorial - 04 Control flow in chisel
Relevant methods of sorting arrays in JS (if you want to understand arrays, it's enough to read this article)
95. (cesium chapter) cesium dynamic monomer-3d building (building)
BSS 7230 flame retardant performance test of aviation interior materials
One click installation with fishros in blue bridge ROS
[programming problem] [scratch Level 2] March 2019 draw a square spiral
【编程题】【Scratch二级】2019.09 绘制雪花图案
随机推荐
【leetcode】day1
串联二极管,提高耐压
Chisel tutorial - 02 Chisel environment configuration and implementation and testing of the first chisel module
[the most detailed in history] statistical description of overdue days in credit
Flask learning record 000: error summary
35岁真就成了职业危机?不,我的技术在积累,我还越吃越香了
关于组织2021-2022全国青少年电子信息智能创新大赛西南赛区(四川)复赛的通知
Use filters to count URL request time
2022.7.7-----leetcode. six hundred and forty-eight
【编程题】【Scratch二级】2019.09 绘制雪花图案
Is 35 really a career crisis? No, my skills are accumulating, and the more I eat, the better
One click installation with fishros in blue bridge ROS
Laser slam learning (2d/3d, partial practice)
QT creator add JSON based Wizard
ROS从入门到精通(九) 可视化仿真初体验之TurtleBot3
FFA与ICGA造影
Visual Studio Deployment Project - Create shortcut to deployed executable
At the age of 35, I made a decision to face unemployment
Binder核心API
[leetcode] 20. Valid brackets