在Visual Studio 2015中检查STL容器

时间:2015-09-18 15:51:57

标签: c++ visual-c++ stl visual-studio-2015

我正在运行Visual Studio Enterprise 2015,版本14.0.23107.0 D14REL。

调试C ++程序时,我看不到STL容器的内容。

我已经获得了#34;在变量窗口中显示对象的原始结构"选项未选中(工具 - >选项 - >调试 - >常规)。

以下是一个说明问题的示例:

#include <list>
#include <string>
#include <vector>

int main()
{
    std::string string = "test";
    std::vector<int> vector{ 4, 5, 6 };
    std::list<std::string> list{ "one", "two", "three" };
    return 0;
}

在Locals或Watch窗口中,我看到以下内容:

list         [...]()
vector       [...](...
  (error)    0
  (error)    0
string       {npos=4294967295}
  (error)    0
  (error)    0

如果我然后检查&#34;显示原始结构......&#34;选项,我可以正确深入到矢量和字符串对象,但仍然不是列表!

我还有其他选择,或者这是VS中的真正错误吗?

7 个答案:

答案 0 :(得分:26)

我遇到了同样的问题。

您需要进入工具 - &gt;选项 - &gt;调试 - &gt;常规并取消选中&#34;使用托管兼容模式&#34;和&#34;使用原生兼容模式&#34;。

答案 1 :(得分:6)

我遇到了同样的问题,但只有当Debugger Type为“Mixed”时(或者我的项目包含C ++ / CLI代码且类型为“Auto”)。使用Debugger Type“Native Only”,std :: vector作为一个整体及其单个元素都正确显示。

您可以使用Debugger Type“Native Only”来调试混合项目的纯C / C ++部分,您只是无法进入C ++ / CLI代码。

另外:如果您在本机调试器中查看时遇到问题,可能需要阅读:https://msdn.microsoft.com/en-us/library/jj620914.aspx

答案 2 :(得分:2)

“在我的盒子上工作”......最后......终于......但特别需要做这些步骤:

  1. 安装VS2015 Update 2,大约需要三个小时
  2. 取消选中工具|中的“使用托管兼容模式”和“使用本机兼容模式”选项选项|调试
  3. 添加此注册开关,如"How to Try It Out"
  4. 中所示

    Reg键:     HKCU\Software\Microsoft\VisualStudio\14.0_Config\AD7Metrics\ExpressionEvaluator\{3A12D0B7-C26C-11D0-B442-00A0244A1DD2}\{994B45C4-E6E9-11D2-903F-00C04FA302A1} 将DWORD LoadInShimManagedEE设置为0

    现在我可以查看标准容器,就像我以前从未做过的那样 ,就像我以前在早期版本中做的那样。我们的大多数本机C ++代码都是从C ++ / CLI代码调用的,所以这个修复是非常必要的。

答案 3 :(得分:1)

不,这不是Visual Studio中的错误!

Microsoft Visual Studio 2005是第一个支持可用于模板类的调试器可视化工具的Visual Studio版本。

您实际上缺少std::<list>

的可视化工具

autoexp.dat文件中添加格式规则。

你可以在这里找到文件

%VSINSTALLDIR%\Common7\Packages\Debugger\autoexp.dat

将新规则附加到[Visualizer]部分。

<强> e.g。查看列表大小

std::list<*,*>{
  preview
    (
      #("[list size=", $e._Mysize, "]")
    )
}

我们正在访问_Mysize实施的std::<list>成员。 _Mysize为您提供列表中元素的数量。

模式匹配:

std::list<*,*>将匹配std::list<int>std::list<int,std::allocator<int> >

std::list<*,*>将匹配std::list<string>std::list<string,std::allocator<string> >

查看子项目

std::list<*,*>{
  children
  (
    #(
      first item: $e._Myhead->_Next->_Myval,
      second item: $e._Myhead->_Next->_Next->_Myval,
      [third item]: $e._Myhead->_Next->_Next->_Next->_Myval
    )
  )
}

甚至

std::list<*,*>{
  children
  (
    #list(size: $c._Mysize,
          head: $c._Myhead->_Next,
          next: _Next
    ) : $e._Myval
  )
}

答案 4 :(得分:0)

对于VS2015,我必须修改autoexp.dat for list:

std::list<*>{
    preview (
        #(
            "[",
            $e._Mypair._Myval2._Mysize,
            "](",
        #list(
            head: $e._Mypair._Myval2._Myhead->_Next,
            size: $e._Mypair._Myval2._Mysize,
            next: _Next
        ) : $e._Myval,
            ")"
        )
    )  

    children (
        #list(
            head: $e._Mypair._Myval2._Myhead->_Next,
            size: $e._Mypair._Myval2._Mysize,
            next: _Next
        ) : $e._Myval
    )
}    

这些变化来自于检查VS2015 stl.natvis并注意到对标有<!-- VC 2015 -->

的各种数据结构所做的更改

我也对其他stl结构进行了适当的更改,但是警告我没有对它们进行全部测试

std::unique_ptr<*>{
    preview (
        #if ($e._Mypair._Myval2 == 0) (
            "empty"
        ) #else (
            #(
                "unique_ptr ",
                *$e._Mypair._Myval2
             )
        )
    )

    children (
        #if ($e._Mypair._Myval2 == 0) (
            #array(expr: 0, size: 0)
        ) #else (
            #([ptr] : $e._Mypair._Myval2)
        )
    )
}

std::_Bind<*>{
    preview (
        #(
            "bind(", $e._Mypair,
            ", ", $e._Mypair._Myval2,
            ")"
        )
    )

children (
        #(
            #([f] : $e._Mypair),
            #([bound_args] : $e._Mypair._Myval2)
            )
    )
}

std::_Mem_fn_wrap<*>{
    preview (
        ; We preview the functor returned by mem_fn() with "mem_fn(<stored member function pointer>)".
        #(
            "mem_fn(",
            $e._Pm,
            ")"
        )
    )

    children (
        ; Member function pointers have no children.
        #array(expr: 0, size: 0)
    )
}

std::_Func_impl<*>{
    preview ( $e._Mypair._Myval2 )
    children (
        #(
            #([functor] : $e._Mypair._Myval2),
            #([allocator] : $e._Mypair)
        )
    )
}

std::function<*>{
    preview (
        #if ($e._Mystorage._Ptrs[$e._Impl] == 0) (
            ; Detecting empty functions is trivial.
            "empty"
        ) #else (
            *$e._Mystorage._Ptrs[$e._Impl]
        )
    )

    children (
        #if ($e._Mystorage._Ptrs[$e._Impl] == 0) (
            ; We make empty functions appear to have no children.
            #array(expr: 0, size: 0)
        ) #else (
            #([functor and allocator] : *$e._Mystorage._ptrs[$e._Impl])
        )
    )
}
std::basic_string<char,*>{
    preview     ( #if (($e._Mypair._Myval2._Myres) < ($e._Mypair._Myval2._BUF_SIZE)) ( [$e._Mypair._Myval2._Bx._Buf,s] ) #else ( [$e._Mypair._Myval2._Bx._Ptr,s] ))
    stringview  ( #if (($e._Mypair._Myval2._Myres) < ($e._Mypair._Myval2._BUF_SIZE)) ( [$e._Mypair._Myval2._Bx._Buf,sb] ) #else ( [$e._Mypair._Myval2._Bx._Ptr,sb] ))

    children (
        #(
            #([size] : $e._Mypair._Myval2._Mysize),
            #([capacity] : $e._Mypair._Myval2._Myres),
            #if (($e._Mypair._Myval2._Myres) < ($e._Mypair._Myval2._BUF_SIZE)) (
                #array(expr: $e._Mypair._Myval2._Bx._Buf[$i], size: $e._Mypair._Myval2._Mysize)
            ) #else (
                #array(expr: $e._Mypair._Myval2._Bx._Ptr[$i], size: $e._Mypair._Myval2._Mysize)
            )
        )
    )
}
std::basic_string<unsigned short,*>|std::basic_string<wchar_t,*>{
    preview     ( #if (($e._Mypair._Myval2._Myres) < ($e._Mypair._Myval2._BUF_SIZE)) ( [$e._Mypair._Myval2._Bx._Buf,su] ) #else ( [$e._Mypair._Myval2._Bx._Ptr,su] ))
    stringview  ( #if (($e._Mypair._Myval2._Myres) < ($e._Mypair._Myval2._BUF_SIZE)) ( [$e._Mypair._Myval2._Bx._Buf,sub] ) #else ( [$e._Mypair._Myval2._Bx._Ptr,sub] ))

    children (
        #(
            #([size] : $e._Mypair._Myval2._Mysize),
            #([capacity] : $e._Mypair._Myval2._Myres),
            #if (($e._Mypair._Myval2._Myres) < ($e._Mypair._Myval2._BUF_SIZE)) (
                #array(expr: $e._Mypair._Myval2._Bx._Buf[$i], size: $e._Mypair._Myval2._Mysize)
            ) #else (
                #array(expr: $e._Mypair._Myval2._Bx._Ptr[$i], size: $e._Mypair._Myval2._Mysize)
            )
        )
    )
}
std::deque<*>{
    preview (
            #(
            "[",
            $e._Mypair._Myval2._Mysize,
            "](",
            #array(
                expr: $e._Mypair._Myval2._Map[(($i + $e._Mypair._Myval2._Myoff) / $e._EEN_DS) % $e._Mypair._Myval2._Mapsize][($i + $e._Mypair._Myval2._Myoff) % $e._EEN_DS],
                size: $e._Mypair._Myval2._Mysize
            ),
            ")"
        )
    )

    children (
        #(
            #array(
                expr: $e._Mypair._Myval2._Map[(($i + $e._Mypair._Myval2._Myoff) / $e._EEN_DS) % $e._Mypair._Myval2._Mapsize][($i + $e._Mypair._Myval2._Myoff) % $e._EEN_DS],
                size: $e._Mypair._Myval2._Mysize
            )
        )
    )
}
std::forward_list<*>{
    preview (
        #(
            "(",
            #list(
                head: $e._Mypair._Myval2._Myhead,
                next: _Next
            ) : $e._Myval,
            ")"
        )
    )

    children (
        #list(
            head: $e._Mypair._Myval2._Myhead,
            next: _Next
        ) : $e._Myval
    )
}
std::vector<bool,*>{
    preview (
        #(
            "[",
            $e._Mysize,
            "](",
            #array(
                expr: (bool)(($e._Myvec._Mypair._Myval2._Myfirst[$i / $e._EEN_VBITS] >> ($i % $e._EEN_VBITS)) & 1),
                size: $e._Mysize
            ),
            ")"
        )
    )

    children (
        #(
            #([size] : $e._Mysize),
            #([capacity] : ($e._Myvec._Mypair._Myval2._Myend - $e._Myvec._Mypair._Myval2._Myfirst) * $e._EEN_VBITS),
            #array(
                expr: (bool)(($e._Myvec._Mypair._Myval2._Myfirst[$i / $e._EEN_VBITS] >> ($i % $e._EEN_VBITS)) & 1),
                size: $e._Mysize
            )
        )
    )
}
std::vector<*>{
    preview (
        #(
            "[",
                $e._Mypair._Myval2._Mylast - $e._Mypair._Myval2._Myfirst,
            "](",
            #array(
                expr: $e._Mypair._Myval2._Myfirst[$i],
                size: $e._Mypair._Myval2._Mylast - $e._Mypair._Myval2._Myfirst
            ),
            ")"
        )
    )

    children (
        #(
            #([size] : $e._Mypair._Myval2._Mylast - $e._Mypair._Myval2._Myfirst),
            #([capacity] : $e._Mypair._Myval2._Myend - $e._Mypair._Myval2._Myfirst),
            #array(
                expr: $e._Mypair._Myval2._Myfirst[$i],
                size: $e._Mypair._Myval2._Mylast - $e._Mypair._Myval2._Myfirst
            )
        )
    )
}
std::map<*>|std::multimap<*>|std::set<*>|std::multiset<*>{
    preview (
        #(
            "[",
            $e._Mypair._Myval2._Myval2._Mysize,
            "](",
            #tree(
                head: $e._Mypair._Myval2._Myval2._Myhead->_Parent,
                skip: $e._Mypair._Myval2._Myval2._Myhead,
                left: _Left,
                right: _Right,
                size: $e._Mypair._Myval2._Myval2._Mysize
            ) : $e._Myval,
            ")"
        )
    )

    children (
        #(
            #tree(
                head: $e._Mypair._Myval2._Myval2._Myhead->_Parent,
                skip: $e._Mypair._Myval2._Myval2._Myhead,
                left: _Left,
                right: _Right,
                size: $e._Mypair._Myval2._Myval2._Mysize
            ) : $e._Myval
        )
    )
}
std::unordered_map<*>|std::unordered_multimap<*>|std::unordered_set<*>|std::unordered_multiset<*>|stdext::hash_map<*>|stdext::hash_multimap<*>|stdext::hash_set<*>|stdext::hash_multiset<*>{
    preview (
        #(
            "[",
            $e._List._Mysize,
            "](",
            #list(
                head: $e._List._Myhead->_Next,
                size: $e._List._Mysize,
                next: _Next
            ) : $e._Myval,
            ")"
        )
    )

    children (
        #list(
            head: $e._List._Myhead->_Next,
            size: $e._List._Mysize,
            next: _Next
            ) : $e._Myval
    )
}

答案 5 :(得分:0)

遇到同样的麻烦。我的环境:赢得10位教授。 x64,VS 2015,update 3,toolset v140,c ++项目。 我甚至看不到字符串。 这个问题似乎是由更新或扩展引起的。

解决方案: 我在另一个系统上完成了VS2015的全新安装(win 7 prof.x64)。这是安装的 更新3(网络安装)。 在这台机器上一切正常:可以看到字符串(不扩展dbg工具提示)。对于容器,尺寸在移动时显示,您可以检查元素。完美。

有什么区别?我不知道。我比较了两者上的.natvis文件 机器和 C:\ Program Files(x86)\ Microsoft Visual Studio 14.0 \ Common7 \ Packages \ Debugger \ autoexp.dat

没有差异。

因此在这种情况下解决方案很常见:卸载VS2015。运行reg清洁剂。重新安装。 开始。我的旧设置从第一次启动和调试检查出现 再次工作。问题解决了。

答案 6 :(得分:0)

我正在运行VS2015 SP3。我花了2个小时尝试互联网告诉我要做的每一个修复。什么都没有用!我的最后一招是重新安装VS(需要几个小时。)所以我去了“添加/删除程序”&gt; “Microsoft Visual Studio Professional 2015”。但是,我尝试进行“修复”,而不是卸载。我不知道是什么原因引起了这个问题,但修复安装修复了它。