std :: string内部缓冲区损坏?

时间:2013-06-19 15:47:47

标签: visual-c++ access-violation assignment-operator stdstring

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

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

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

这是我无法提供SSCCE的情况,因为我不能故意复制错误。调用错误的代码只是实例mutator中的典型字符串值赋值,如:

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()
    }
};

是什么导致这个?谁看过这个吗?关于在哪里寻找下一步的任何建议?

1 个答案:

答案 0 :(得分:2)

s._Bx._Buf不是指针,它是内部小缓冲区std :: string用于保存小字符串。这称为小缓冲区优化或SBO。 s._Bx是缓冲区和_Ptr的并集,如果内部缓冲区太小,则指向堆缓冲区的指针。因此,对于小字符串,s._Bx._Ptr 应该无效;毕竟,它的存储空间正用于小字符串。

无论如何......如果你遇到访问冲突,一切都不顺利。在这种情况下,最可能的原因是你不小心搞乱了std :: string的内存,很可能是因为某些缓冲区溢出或者在某处使用了free-after-free。这不是有趣的任务,而是它之前发生的事情。