当前位置:网站首页>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
边栏推荐
- 【編程題】【Scratch二級】2019.12 飛翔的小鳥
- Chisel tutorial - 04 Control flow in chisel
- Using Google test in QT
- QT creator add JSON based Wizard
- CoinDesk评波场去中心化进程:让人们看到互联网的未来
- Two small problems in creating user registration interface
- 【编程题】【Scratch二级】2019.03 垃圾分类
- Resolve the URL of token
- 腾讯安全发布《BOT管理白皮书》|解读BOT攻击,探索防护之道
- How to measure whether the product is "just needed, high frequency, pain points"
猜你喜欢

第四期SFO销毁,Starfish OS如何对SFO价值赋能?

Rectification characteristics of fast recovery diode

数据湖(十五):Spark与Iceberg整合写操作

BSS 7230 flame retardant performance test of aviation interior materials
![[programming problem] [scratch Level 2] March 2019 draw a square spiral](/img/fa/ae9dabdd36ba77b1f4644dd23bee93.png)
[programming problem] [scratch Level 2] March 2019 draw a square spiral

FFA与ICGA造影

Detailed explanation of interview questions: the history of blood and tears in implementing distributed locks with redis

Is 35 really a career crisis? No, my skills are accumulating, and the more I eat, the better

QT creator add JSON based Wizard

某马旅游网站开发(登录注册退出功能的实现)
随机推荐
52岁的周鸿祎,还年轻吗?
[basis of recommendation system] sampling and construction of positive and negative samples
Seven years' experience of a test engineer -- to you who walk alone all the way (don't give up)
An example analysis of MP4 file format parsing
一键免费翻译300多页的pdf文档
Ping error: unknown name or service
SQL knowledge summary 004: Postgres terminal command summary
Introduction knowledge system of Web front-end engineers
2022.7.7-----leetcode.648
FFA与ICGA造影
80%的人答错,苹果logo上的叶子到底朝左还是朝右?
Is 35 really a career crisis? No, my skills are accumulating, and the more I eat, the better
Visual Studio Deployment Project - Create shortcut to deployed executable
[path planning] use the vertical distance limit method and Bessel to optimize the path of a star
Connect diodes in series to improve voltage withstand
用語雀寫文章了,功能真心强大!
webflux - webclient Connect reset by peer Error
Binary sort tree [BST] - create, find, delete, output
Codeworks 5 questions per day (average 1500) - day 8
Preliminary test of optical flow sensor: gl9306