5

我创建了一个类 SettingsClass,其中包含静态字符串,这些字符串包含 MySQL C++ 连接器库要使用的数据库连接字符串(例如主机名、数据库名、用户名、密码)。

每当一个函数需要连接到数据库时,它都会在这些静态字符串上调用 .c_str() 函数。例如:

Class SettingsClass
{
    public:
    static string hostname;
    ...
}SettingsClass;
string SettingsClass::hostname;

//A function that needs to connect to the DB uses:
driver = get_griver_instance();
driver->connect(SettingsClass.hostname.c_str(),...);

静态字符串在进程生命周期中填充一次。它的值是从配置文件中读取的。

我的应用程序是多线程的。我是否以安全的方式使用 c_str() ?

4

4 回答 4

6

c_str() 本身应该是线程安全的。但是,如果您有另一个线程访问(写入)您正在使用 c_str() 的字符串,那么您正在玩汽油池中的火柴。

通常 c_str() 是通过在现有字符串的末尾添加一个零值(空字符 0x00,而不是 0x30 的零字符)来实现的(如果那里还没有),并传回 where 的地址字符串被存储。

任何有兴趣的人都可以在这里阅读 libstdc++ 代码: libstdc++, basic_string.h 有趣的行是 1802 和 294 - 1802 是 c_str() 函数,而 294 是 c_str() 调用的函数。

于 2012-12-28T16:39:47.553 回答
2

至少在理论上,该标准允许实现不是线程安全的。在实践中,我认为您不会冒任何风险(尽管形式上可能存在未定义的行为),但如果您想确定,只需.c_str()在初始化期间对所有字符串调用一次(在线程启动之前) . 该标准保证返回指针的有效性,直到调用下一个非常量函数(即使您不保留它的副本),这意味着实现不能改变任何数据。

于 2012-12-28T16:53:15.287 回答
0

由于string类型是恒定的(因此,假设它是不可变的),它永远不会被修改。任何只读取它的函数都应该是线程安全的。

所以,我认为.c_str()是线程安全的。

于 2012-12-28T16:39:35.650 回答
0

只要std::string变量在您的线程启动之前正确初始化并且之后使用const char*表示通过不更改c_str()应该是线程安全的。

于 2012-12-28T16:44:37.407 回答