当前位置:网站首页>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
边栏推荐
- HDU - 1260 tickets (linear DP)
- FFA与ICGA造影
- Codeworks 5 questions per day (average 1500) - day 8
- HB 5469 combustion test method for non-metallic materials in civil aircraft cabin
- Stm32f1 and stm32cubeide programming example - rotary encoder drive
- 手写一个模拟的ReentrantLock
- Chisel tutorial - 04 Control flow in chisel
- 如何衡量产品是否“刚需、高频、痛点”
- The function is really powerful!
- QT creator add custom new file / Project Template Wizard
猜你喜欢
串联二极管,提高耐压
Go learning notes (1) environment installation and hello world
new和delete的底层原理以及模板
光流传感器初步测试:GL9306
80%的人答错,苹果logo上的叶子到底朝左还是朝右?
C language 005: common examples
Trust orbtk development issues 2022
Is 35 really a career crisis? No, my skills are accumulating, and the more I eat, the better
Set up personal network disk with nextcloud
FFA与ICGA造影
随机推荐
Robomaster visual tutorial (1) camera
Flask learning record 000: error summary
Redis caching tool class, worth owning~
The difference between -s and -d when downloading packages using NPM
10 schemes to ensure interface data security
Sqlite数据库存储目录结构邻接表的实现2-目录树的构建
Archery installation test
全自动化处理每月缺卡数据,输出缺卡人员信息
HDU - 1260 tickets (linear DP)
@Detailed introduction of configuration annotation
Tools for debugging makefiles - tool for debugging makefiles
[leetcode] 20. Valid brackets
[programming problem] [scratch Level 2] draw ten squares in December 2019
Anaconda+pycharm+pyqt5 configuration problem: pyuic5 cannot be found exe
Cmake learning notes (1) compile single source programs with cmake
Set up personal network disk with nextcloud
[programming questions] [scratch Level 2] March 2019 garbage classification
SQL 使用in关键字查询多个字段
limit 与offset的用法(转载)
[basis of recommendation system] sampling and construction of positive and negative samples