2013-06-19 135 views
0

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

使用Visual Studio调试器,我参考的内部缓冲区是char[]实例成员std::string::_Bx::_Buf。这通常包含由std::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() 
    } 
}; 

这是什么原因?有没有人见过这个?任何关于下一步看什么的建议?

+0

您发布的代码也有同样的问题?我们可以用它来检查 – qwr

+0

@QWR否,那个代码当然不应该有同样的问题。我只是很快打出来,所以没有任何错别字等。这是一个玩具的例子。请参阅https://en.wikipedia.org/wiki/Mutator_method#C.2B.2B_example – taz

+0

你是否在整个项目中使用std :: string。或者你也可以在某处传递char *。我怀疑它可能是这个原因。有如何实现明确的方法关键字行为http://stackoverflow.com/questions/175689/can-you-use-keyword-explicit-to-prevent-automatic-conversion-of-method-parameter – qwr

回答

1

s._Bx._Buf不是一个指针,它是内部小缓冲区std :: string用于保存小字符串。这被称为小缓冲优化或SBO。 s._Bx是缓冲区和_Ptr的联合,如果内部缓冲区太小,则指向分配给堆缓冲区的指针。所以对于小字符串,s._Bx._Ptr应该无效;毕竟,它的存储是用于小字符串的。

无论如何...如果您遇到访问违规,一切都不好。在这种情况下,最可能的原因是您意外地与std :: string的内存混淆了,很可能是由于缓冲区溢出或在某处释放后使用。这不是有趣的任务,而是它之前发生的事情。

+0

感谢有关内部缓冲区的信息。在这种情况下,“小”是如何定义的? (你的意思是“所以对于小字符串,_'s._Bx._Buf'_应该是无效的?编辑:我现在明白了)有没有办法让调试器提醒我,如果我不小心混淆了'std :: string''s memory? – taz

+0

1)“Small”是由MS工程师为了找到最佳尺寸而做的实验所定义的,代码中可能有一些常数2)不,我不是这个意思,它是'_Ptr'应该是无效的,因为'_Buf'包含字符串数据并且它位于相同的内存中。3)http:// stackoverflow。com/questions/621535/what-are-data-breakpoints –

+0

要详细说明3),请在初始创建字符串之后设置正常断点,使用调试器查找其地址,并在其中设置数据断点。 –

相关问题