1

我正在观察一个std::string赋值运算符 ( =) 导致写入 LHS 的访问冲突。在 MSVC++ 调试模式下,LHS 内部缓冲区指向无效地址。我不熟悉 MSVC++ 的内部结构,std::string但我之前曾假设内部缓冲区指针永远不应该是无效的。

使用 Visual Studio 调试器,我引用的内部缓冲区是char[]实例成员std::string::_Bx::_Bufstd::string这通常保存由对象表示的以空字符结尾的字符串的地址。看来这std::string::_Bx._Ptr也是一个char *指向该地址的指针。

在某些情况下,我经常遇到这种情况,但我无法确定该地址如何或何时变得无效。如果有东西破坏了这个值,调试器不会提醒我吗?有没有办法将 Visual Studio 调试器设置为在std::string::_Bx::_Buf访问写入时暂停?

在这种情况下,我无法提供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 的内存,很可能是由于某些缓冲区溢出或某处释放后使用。有趣的不是任务,而是它之前发生的事情。

于 2013-06-19T15:56:02.657 回答