智能指针
为了避免
- 遗忘释放内存、资源
- 中途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;