智能指针
为了避免
- 遗忘释放内存、资源
- 中途return,需要多处调用释放内存,资源
- 放到容器中的指针,错误释放内存,资源
我们写c++程序时,都使用智能指针来帮助管理内存和资源。c++不是c,提供的便捷要利用起来:
不使用任何明确的delete语句
熟悉并熟练使用 std::auto_ptr, boost::shared_ptr, boost::shared_array, boost::scoped_ptr, boost::scoped_array
Don’t
动态分配内存,不要使用以下方法. 因为 1 处会抛出异常造成delete无法释放。
int n = 100;
char *p = new char[n];
....// 1: 使用p
delete []p;
Do
使用以下任一方法分配、管理内存
int n = 100;
std::vector v;
v.resize(n);
....// 使用 &v.at(0)或者&v[0], 与上面的p等价
// 不需要调用delete[]
或者
int n = 100;
boost::shared_array p(new char[n]); // 或者使用boost::scoped_array
// 不需要调用delete[]
不要直接调用系统锁资源和解锁资源
使用以下方法管理mutex
void foo(const char* fileName)
{
boost::unique_lock lock(gMutex);
// 竞争区域的代码
return;
}
不要直接调用close, fclose, mysql_close, mysql_free_result, curl_easy_cleanup这些方关闭文件、数据库等资源的方法
Don’t
打开文件,关闭文件,不要使用以下方法. 因为 2 处会抛出异常造成fclose无法释放。
FILE *file = fopen(filename, "rb");
// 2, 使用 file
fclose(file);
Do
使用以下方法管理文件指针
struct CFileCloser{
void operator ()(FILE* file){
if (file) fclose(file);
}
};
void foo(const char* fileName)
{
boost::shared_ptr backgroundFile(fopen(fileName, "rb"), CFileCloser());
}
使用以下方法管理MYSQL_RES
boost::shared_ptr
resultSp(mysql_store_result(&mysql_), mysql_free_result);
if (!resultSp) {
LOG4CXX_ERROR(gLogger, "error in mysql connection: " << mysql_error(&mysql_));
return false;
}
boost::uint64_t numRows = mysql_num_rows(resultSp.get());
MYSQL_ROW row = mysql_fetch_row(resultSp.get());
使用以下方法管理CURL
bool performUrl(const std::string url, std::string& result)
{
std::stringstream oss;
CURL* curl = curl_easy_init();
boost::shared_ptr pointer(curl, curl_easy_cleanup);
if(curl)
{
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 1);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &oss);
curl_easy_perform(curl);
result = oss.str();
return true;
}
return false;
}
换掉一些可能造成crash的不安全函数
使用std::ostringstream或者snprintf代替sprintf
std::ostringstream oss;
oss << DaemonConfig::disconnectNotifyURL << "?id=" << playerId;