C++ Boost智能指针小测

请阅读该文档(http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/shared_ptr.htm),回答以下问题:

  1. boost::shared_ptr能存放数组指针吗?如果不能,应该使用什么?
  2. 与std::auto_ptr相比,boost::shared_ptr有什么优势?
  3. 对于一般指针的dynamic_cast,boost::shared_ptr应该怎么cast?
  4. 什么情况下使用shared_from_this?
  5. 如何获取shared_ptr中保存的具体对象的指针?
  6. 如果要释放某shared_ptr对指针的引用,应该怎么操作?
  7. 什么情况使用weak_ptr?
  8. shared_ptr怎么管理file, MYSQL_RES, CURL等资源?

C++程序注意事项

智能指针

为了避免

  1. 遗忘释放内存、资源
  2. 中途return,需要多处调用释放内存,资源
  3. 放到容器中的指针,错误释放内存,资源

我们写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;

CSDN 600万用户密码泄露事件受害者查询

CSDN 600万用户密码泄露事件受害者查询 泄露么
如果查询结果有你的密码,请尽快修使用这个密码的所有账户的密码,包括你的263邮箱,GMail, 支付宝,淘宝等.

一个不错的NodeJS教程

介绍了NodeJS的历史,优势劣势, 安装,使用方法

Server-Side JavaScript Developement – Node.JS Quick Tour

c++版本的普通程序员,文艺程序员,2b程序员和失足程序员

逆序输出字符串

普通程序员

#include <iostream>
using namespace std;
char *str = "n!dlrow olleh";

int main (int argc, char** argv) {
  for(char *p = str + strlen(str); p >= str; p--){
    cout << *p;
  }
  return 0;
}

文艺程序员

#include <iostream>
#include <iterator>
#include <algorithm>

using namespace std;

static char *str = "n!dlrow olleh";

int main (int argc, char** argv) {
  reverse_copy(str, str + strlen(str) + 1, 
    ostream_iterator<char>(cout, ""));
  return EXIT_SUCCESS;
}

2B程序员

#include <iostream.h>

static char *str = "n!dlrow olleh";

int main () {
  char *p = str + strlen(str);
  putchar(*(p--));
  putchar(*(p--));
  putchar(*(p--));
  putchar(*(p--));
  putchar(*(p--));
  putchar(*(p--));
  putchar(*(p--));
  putchar(*(p--));
  putchar(*(p--));
  putchar(*(p--));
  putchar(*(p--));
  putchar(*(p--));
  putchar(*(p--));
  putchar(*(p--));
}

失足程序员

#include <iostream>
using namespace std;

const char str[] = "n!dlrow olleh";

template< int N >
struct Printer{
    void operator()(){
        cout << *(str + N);
    }
};

template< template < int > class C, int N >
struct Rev{
    Rev(){
        C< N >()();
        Rev< C, N - 1>();
    }
};

template< template < int > class C >
struct Rev<C, 0>{
    Rev(){
        C< 0 >()();
    }
};

template <int N>
int len_trait(const char (&)[N])
{
    static Rev< Printer, N > rev;
    return 0;
}

static int dummy = len_trait(str);

int main(int argc, char** argv)
{
    return EXIT_SUCCESS;
}

MongoDB运行状态、性能监控,分析

这篇文章的目的是让你知道怎么了解你正在运行的Mongdb是否健康。
» Read more…

统计分析svn用户每天提交的代码数

这个脚本可以分析svn 用户每天提交的代码数,有了数量的横向比较,也就知道团队里面哪个成员是有很大的潜力提升,帮助其提高。

可以在这里https://gist.github.com/1297604获取最新的代码,复制黏贴到文件里面,chmod +x 后,即可使用。

» Read more…

vim查找文件里面行的长度超过指定值的行

查找一行里面超过70个字符的行

/\%>70v.\+

用python flup调试nginx fastcgi配置错误造成404的问题

最近几年php服务器都倾向于使用nginx+fastcgi/php-fpm。

但是配置nginx fastcgi遇到最棘手的问题,就是配置失败时,没有调试手段,不知道哪里有错误,怎么去修改nginx的配置。以前都是盲目尝试,直至配置成功。费时,没有线索。

特别是fastcgi有一堆变量,例如SCRIPT_FILENAME、PATH_INFO、QUERY_STRING、DOCUMENT_URI,如果在配置失败时能看到这些变量的值,对调整配置文件是很有指导意义的。

» Read more…

一行Linux命令查找所有非UTF-8编码的文件,再一行命令,都转换成UTF-8

开始之前,请先安装enca这个软件包。enca是Linux等系统下用来查看文件编码和转换文件编码的工具。

下面一行Linux命令能够查找当前目录下所有文件中,哪些文件不是UTF-8编码。我对文件加了些限制,用find命令时候,排除了所有目录下的.svn目录,且只查找后缀为.php的文件。

命令1

jw@~/sqlite>
find . ! -iregex '.*\.svn.*' -type f -name '*.php' -exec bash -c "enca -L zh_CN {}|grep GB2312 > /dev/null && echo {}" \;
./sqlite_utility.php
./sqlite_result.php
./sqlite_forge.php
./sqlite_driver.php

既然找到了这些非UTF8编码的文件,接下来再用一条命令将他们都转换成UTF8编码

命令2

jw@~/sqlite>
find . ! -iregex '.*\.svn.*' -type f -name '*.php' -exec bash -c "enca -L zh_CN {}  | grep GB2312 >/dev/null && enconv -L zh_CN -x UTF-8 {}" \;

当你用命令2 全部转换完成后,如果你期待命令1的输出为空,那么你就错了。实际上英语字母的utf8编码和ASCII编码是一样的。当一个全是英文字母的文件用UTF8 w/o BOM编码保存,那么enca会识别他是一个ACSII编码的文件。所以,你猜到了,命令2做了一些无用功:)