当前位置:网站首页>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
边栏推荐
- Tools for debugging makefiles - tool for debugging makefiles
- Apng2gif solutions to various problems
- 串联二极管,提高耐压
- 某马旅游网站开发(对servlet的优化)
- Kubectl 好用的命令行工具:oh-my-zsh 技巧和窍门
- Robomaster visual tutorial (11) summary
- Gorm Association summary
- Detailed explanation of interview questions: the history of blood and tears in implementing distributed locks with redis
- FFA and ICGA angiography
- Handwriting a simulated reentrantlock
猜你喜欢
Basic learning of SQL Server -- creating databases and tables with the mouse
Binary sort tree [BST] - create, find, delete, output
Set up personal network disk with nextcloud
ROS从入门到精通(九) 可视化仿真初体验之TurtleBot3
SQL connection problem after downloading (2)
[path planning] use the vertical distance limit method and Bessel to optimize the path of a star
80%的人答错,苹果logo上的叶子到底朝左还是朝右?
快速上手使用本地测试工具postman
C - linear table
第四期SFO销毁,Starfish OS如何对SFO价值赋能?
随机推荐
[programming questions] [scratch Level 2] March 2019 garbage classification
Kubectl's handy command line tool: Oh my Zsh tips and tricks
new和delete的底层原理以及模板
数据库查询——第几高的数据?
QT creator add JSON based Wizard
One click free translation of more than 300 pages of PDF documents
Relevant methods of sorting arrays in JS (if you want to understand arrays, it's enough to read this article)
Gorm Association summary
Magic fast power
一鍵免費翻譯300多頁的pdf文檔
Basic learning of SQL Server -- creating databases and tables with the mouse
Database interview questions + analysis
某马旅游网站开发(对servlet的优化)
[basis of recommendation system] sampling and construction of positive and negative samples
Archery installation test
Install sqlserver2019
Fully automated processing of monthly card shortage data and output of card shortage personnel information
QT and OpenGL: loading 3D models using the open asset import library (assimp) - Part 2
Stm32f1 and stm32cubeide programming example - rotary encoder drive
Two small problems in creating user registration interface