VS调试STL问题总结

---恢复内容开始---html

  之前写代码总觉用本身写的东西比较牛逼,vector?stack?为何不本身实现。后来才认识到这是个幼稚的想法!首先每次都本身实现是一种重复劳动;其次,本身写的话很难保证没有bug;效率每每也不如STL。STL的优点不在此赘述,最近使用STL的时候发现调试时,监视器中的内容不忍直视,乱七八糟的,通过一番了解才慢慢发现问题所在。在这里总结一下,也但愿能帮到遇到一样问题的同窗。工具

  首先贴出来,我用的vs2015社区版 update3 调试代码时遇到的问题。item_vec的声明以下:spa

  vector<string> item_vec;debug

  当我想查看一下item_vec中的内容时,watch中的内容以下:调试

  看到这个,个人心里基本是崩溃的,这还看个毛线啊。回过头来想一想,为何vs显示的是这些“乱七八糟”的东西?由于这些正是vector对象的成员。想一想一下,vs在提供调试的时候,咱们查看一对象a,vs就应该给我显示对象a的成员和值,那我想查看vector的内容时,vs就应该像上面这样显示,没有问题。可是回想之前使用stl,调试时显示的好像不是这种东西,问题出在哪里?code

  一番查找以后,了解到这个属于vs可视化调试的内容。可视化调试大概就是区别于gdb,提供可视化调试界面的功能。强大的vs在想,我怎么为STL提供给友好的可视界面,那我为STL单独设置一种显示行不行,vector对象显示size, capacity, vector中的全部元素列表等等。这样这个问题貌似就解决了!!!htm

  然而这个问题并无这么简单,这样作只能解决STL的显示问题,若是用户本身实现了STL功能,或者本身使用了更适合本身的第三方类库,这个时候STL类的定义都彻底不同了,vs就没有办法显示了。推而广之,若是任意一个用户定义的类,并且这个类和STL中的类同样复杂,而且调试的时候常常须要查看这个类的对象的状态,这个时候vs就没法知足要求的。仔细一想这个问题就不能用上面的方案解决。因此微软提供了更牛叉的解决方案:用户自定义显示。对象

  大概的想法是这样的,“我定义的类我作主”,vs提供一种工具,让你本身来决定怎么在调试的时候显示这个类的对象。具体能够访问:https://msdn.microsoft.com/zh-cn/library/jj620914.aspx。简而言之就是,你可使用一种.natvis的文件来定义一个类的对象在调试时的显示。大概的定义方式以下:blog

<Type Name="std::vector<*>">
    <DisplayString>{{ size={_Mylast - _Myfirst} }}</DisplayString>
    <Expand> 
        <Item Name="[size]" ExcludeView="simple">_Mylast - _Myfirst</Item>
        <Item Name="[capacity]" ExcludeView="simple">_Myend -_Myfirst</Item>
        <ArrayItems> 
            <Size>_Mylast - _Myfirst</Size>
            <ValuePointer>_Myfirst</ValuePointer>
        </ArrayItems>
    </Expand>
</Type>                            

  这个是微软给出的样例,在vs2013中用来定义vector的显示形式,大概的效果以下:ci

  厉害了个人哥,这个就舒服不少嘛!参考微软官方的指南,你就能够为本身的类定义你想要的显示形式。这样就在调试代码的时候就不用加一些为了查看某些值而写一些额外的代码了。

  vs在安装时,STL中的类都有默认的显示方案,大概就是上面这张图中的效果。

  上面讲的是vs自定义类显示的原理,那为何个人vs还会有显示问题,不是有默认的显示吗?其实这是vs 社区版update3的一个bug,参考这个连接:https://connect.microsoft.com/VisualStudio/feedback/details/1676171/change-in-c-stl-container-implementation-causes-debug-visualizer-error。bug产生的缘由以下:.natvis文件时XML文件,因此正常是须要加上验证的,这个验证文件在C:\Program Files (x86)\Microsoft Visual Studio 14.0\Xml\Schemas\1033\natvis.xsd。可是vs2015社区版update3的这个文件不知道为何使用的是vs2015RTM版本的xsd文件。致使,vs默认的stl.natvis文件中的一些定义不无经过验证,相应的内容就没法生效,在vs看来相应的内容就只能用raw_data的形式显示。这个问题会在下个版本中解决,目前只能等。上面的链接中有人提到了一种解决的偏方,有兴趣的同窗能够尝试一下,个人vs下没有偏方中描述的文件,因此没办法用。

  

  最后再说一说遇到这种现实问题应该怎么去确认问题的缘由,若是下次vs再有这种bug,你也能够本身尝试去确认bug的缘由。

  在vs中能够设置以原始数据的形式查看。“工具”->“选项”->“调试”->“常规”下能够设置“在变量窗口中显示对象的原始数据”,若是但愿.natvis生效,须要把这一项取消。

  在查看STL(以vector为例)对象时,能够查看output窗口,若是.natvis文件解析异常,会报错。在修改了.natvis文件后能够在watch窗口中执行.natvisreload命令从新加在.natvis文件。

  也能够为项目添加.natvis文件,该.natvis文件只会在该项目中生效,而且,修改该.natvis文件会当即生效。参考https://www.zhihu.com/question/41286979。

  关于stl.natvis文件,若是须要修改stl.natvis,请注意vs使用的stl版本,不一样版本stl对容器元素的声明会不同,如通用的vector显示:

  vs2013:

<Type Name="std::vector&lt;*&gt;" Priority="MediumLow">
    <DisplayString>{{ size={_Mylast - _Myfirst} }}</DisplayString>
    <Expand>
        <Item Name="[capacity]" ExcludeView="simple">_Myend - _Myfirst</Item>
        <ArrayItems>
            <Size>_Mylast - _Myfirst</Size>
            <ValuePointer>_Myfirst</ValuePointer>
        </ArrayItems>
    </Expand>
 </Type>

  vs2015:

<Type Name="std::vector&lt;*&gt;">
    <DisplayString>{{ size={_Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst} }}</DisplayString>
    <Expand>
        <Item Name="[capacity]" ExcludeView="simple">_Mypair._Myval2._Myend - _Mypair._Myval2._Myfirst</Item>
        <Item Name="[allocator]" ExcludeView="simple">_Mypair</Item>
        <ArrayItems>
              <Size>_Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst</Size>
            <ValuePointer>_Mypair._Myval2._Myfirst</ValuePointer>
        </ArrayItems>
    </Expand>
</Type>

 

  最后的最后,若是是想vs2015社区版update3这样的bug,暂时没法修复时。在watch窗口item_vec[0]会失败,可使用"&(item_vec.operator[](0)),n",这个表达式能够查看vector中n个元素。

相关文章
相关标签/搜索