我有一个指向以\0
结尾的字符串的 char* p
变量,如何以安全的方式在C++中创建一个string
?
以下是一个不安全的版本:
string foo()
{
char *p = get_string();
string str( p );
free( p );
return str;
}
显然的解决方法是使用 try-catch - 是否有更简单的方法?
是的 - 基于堆栈的展开。《现代 C++ 设计》提供了一般解决方案,但在这种情况下,您可以使用
struct Cleanup {
void* toFree;
Cleanup(void* toFree) : toFree(toFree) {}
~Cleanup() { free(toFree); }
private:
Cleanup(Cleanup&);
void operator=(Cleanup&);
};
好的,如果get_string()
返回NULL,则p
不指向以0结尾的字符串;这就是问题所在,因为接受指向以0结尾的C字符串的std::string
构造函数无法处理NULL,而NULL和两打香蕉一样都是以0结尾的C字符串。
因此,如果get_string()
是您自己的函数(而不是库函数),那么也许您应该确保它不能返回NULL。例如,您可以让它返回所寻找的std::string
本身,因为它知道自己的状态。否则,我会使用此答案中的Cleanup
作为帮助程序来执行此操作,以确保p
不会泄漏(如Martin York在评论中建议的那样)。
string foo()
{
const char* p = get_string();
const Cleanup cleanup(p);
const std::string str(p != NULL ? p : "");
return str;
}
我们通常在以下情况下使用ScopeGuard:
string foo()
{
char *p = get_string();
ScopeGuard sg = MakeGuard(&free, p);
string str( p );
return str;
}