1

std::string代入演算子 ( =) が LHS へのアクセス違反の書き込みを引き起こしているのを観察しています。MSVC++ デバッグ モードでは、LHS 内部バッファが無効なアドレスを指しています。私は MSVC++ の内部構造に精通していませんがstd::string、以前は内部バッファー ポインターが無効になることはないと想定していました。

Visual Studio デバッガーを使用して参照する内部バッファーは、char[]インスタンス メンバーstd::string::_Bx::_Bufです。これは通常、オブジェクトによって表されるヌル終了文字ストリングのアドレスを保持しstd::stringます。std::string::_Bx._Ptrchar *このアドレスへのポインタのようです。

特定の状況でこれが頻繁に発生しますが、このアドレスがいつ、どのように無効になるかを判断できません。何かがこの値を壊した場合、デバッガーは私に警告しませんか? std::string::_Bx::_Buf書き込みのためにアクセスしたときに一時停止するように Visual Studio デバッガーを設定する方法はありますか?

これは、意図的にエラーを再現できないため、 SSCCEを提供できないシナリオです。エラーを呼び出すコードは、次のようなインスタンス ミューテーターでの典型的な文字列値の割り当てです。

class MyClass {
protected:
    std::string myValue;
public:
    void setValue(std::string value) {
        myValue = value; // ACCESS VIOLATION from std::string::operator=()
    }
};

class OtherClass {
    static myFunc() {
        std::string myString("some value");
        MyClass *myClass = new MyClass();
        myClass->setValue(myString); // ACCESS VIOLATION from setValue()
    }
};

何が原因でしょうか? 誰もこれを見たことがありますか?次にどこを見るべきかについての提案はありますか?

4

1 に答える 1

2

s._Bx._Bufはポインターではなく、小さな文字列を保持するために std::string が使用する内部の小さなバッファーです。これは、スモール バッファー最適化 (SBO) と呼ばれます。 内部バッファーが小さすぎる場合に割り当てられるヒープ バッファーへのポインターs._Bxと、バッファーの和集合です。_Ptrしたがって、小さな文字列の場合、無効にs._Bx._Ptr する必要があります。結局のところ、そのストレージは小さな文字列に使用されています。

とにかく…アクセス違反をしたら、すべてがうまくいっているわけではありません。このような場合、最も可能性の高い原因は、std::string のメモリを誤って台無しにしたことです。おそらく、何らかのバッファ オーバーフローまたは use-after-free が原因です。興味深いのは課題ではなく、その前に起こっていることです。

于 2013-06-19T15:56:02.657 に答える