我观察到一个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,因为我无法故意复制错误。调用错误的代码只是实例突变器中的典型字符串值赋值,例如:
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()
}
};
什么原因可能导致这种情况?以前有人见过吗?关于下一步去哪里看有什么建议吗?
s._Bx._Buf
不是指针,它是内部小缓冲区 std::string 用于保存小字符串。这称为小缓冲区优化或 SBO。 s._Bx
是缓冲区和_Ptr
的联合,是指向堆缓冲区的指针,如果内部缓冲区太小,则会分配堆缓冲区。所以对于小字符串,s._Bx._Ptr
应该是无效的;毕竟,它的存储用于小字符串。
无论如何。。。如果您遇到访问冲突,则一切都不好。在这种情况下,最可能的原因是你不小心弄乱了 std::string 的内存,很可能是由于某些缓冲区溢出或释放后使用。有趣的不是作业,而是它之前发生的事情。