5

MySQL C++ コネクタ ライブラリで使用されるデータベース接続文字列 (ホスト名、データベース名、ユーザー名、パスワードなど) を保持する静的文字列を含むクラス SettingsClass を作成しました。

関数がデータベースに接続する必要があるときはいつでも、これらの静的文字列に対して .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(),...);

静的文字列は、プロセスの存続期間中に 1 回入力されます。その値は構成ファイルから読み取られます。

私のアプリケーションはマルチスレッドです。安全な方法で c_str() を使用していますか?

4

4 に答える 4

6

c_str() 自体はスレッドセーフである必要があります。ただし、c_str() を取得している文字列にアクセス (書き込み) する別のスレッドがある場合は、ガソリンのプールに座っているマッチで遊んでいます。

通常、 c_str() は、既存の文字列の末尾にゼロ値 (0x30 であるゼロの文字ではなく、ヌル文字 0x00) を追加することによって実装され (まだ存在しない場合)、そのアドレスを返します。文字列が格納されます。

興味のある方は、ここで libstdc++ コードを読むことができます: libstdc++, basic_string.h 興味深い行は 1802 と 294 です。1802 は c_str() 関数で、294 は c_str() が呼び出す関数です。

于 2012-12-28T16:39:47.553 に答える
2

少なくとも理論的には、この標準ではスレッドセーフではない実装が許可されています。実際には、リスクはないと思いますが(正式には未定義の動作が発生する可能性があります)、確認したい場合は.c_str()、初期化中(スレッドが開始される前)にすべての文字列を1回呼び出すだけです。 。この標準は、次のnon-const関数が呼び出されるまで(コピーを保持していなくても)、返されたポインターの有効性を保証します。つまり、実装はデータを変更できません。

于 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 に答える