当前位置:网站首页>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
边栏推荐
- How does starfish OS enable the value of SFO in the fourth phase of SFO destruction?
- 一键免费翻译300多页的pdf文档
- 全自动化处理每月缺卡数据,输出缺卡人员信息
- 串联二极管,提高耐压
- 某马旅游网站开发(登录注册退出功能的实现)
- 一鍵免費翻譯300多頁的pdf文檔
- Data analysis series 3 σ Rule / eliminate outliers according to laida criterion
- webflux - webclient Connect reset by peer Error
- Enterprise application demand-oriented development of human resources department, employee attendance records and paid wages business process cases
- Postgres timestamp to human eye time string or millisecond value
猜你喜欢

Solutions to problems in sqlserver deleting data in tables
![[programming problem] [scratch Level 2] December 2019 flying birds](/img/5e/a105f8615f3991635c9ffd3a8e5836.png)
[programming problem] [scratch Level 2] December 2019 flying birds

光流传感器初步测试:GL9306

Opengl3.3 mouse picking up objects

Les mots ont été écrits, la fonction est vraiment puissante!

How to measure whether the product is "just needed, high frequency, pain points"

Two small problems in creating user registration interface

快速回复二极管整流特性

Ping error: unknown name or service

Install sqlserver2019
随机推荐
在网页中打开展示pdf文件
Opengl3.3 mouse picking up objects
Pigsty: out of the box database distribution
Problems faced when connecting to sqlserver after downloading (I)
How did a fake offer steal $540million from "axie infinity"?
光流传感器初步测试:GL9306
【编程题】【Scratch二级】2019.12 绘制十个正方形
Chisel tutorial - 03 Combinatorial logic in chisel (chisel3 cheat sheet is attached at the end)
STM32F1與STM32CubeIDE編程實例-旋轉編碼器驅動
[programming problem] [scratch Level 2] December 2019 flying birds
The difference between get and post
数据库查询——第几高的数据?
Codeworks 5 questions per day (average 1500) - day 8
PostGIS learning
2022-07-07:原本数组中都是大于0、小于等于k的数字,是一个单调不减的数组, 其中可能有相等的数字,总体趋势是递增的。 但是其中有些位置的数被替换成了0,我们需要求出所有的把0替换的方案数量:
智慧监管入场,美团等互联网服务平台何去何从
Orthodontic precautions (continuously updated)
【編程題】【Scratch二級】2019.12 飛翔的小鳥
Emotional post station 010: things that contemporary college students should understand
Robomaster visual tutorial (10) target prediction