1

二重リンク リストのnatvis ビジュアライザーを作成したいと思います。リストにはカウント ノードが格納されておらず、拡張が停止しないため、簡単な方法はうまく機能しません (next は決して null ではなく、リストの最後の項目はリスト ルートを指しています)。

<Type Name="TListBidir&lt;*&gt;">
    <Expand>
        <LinkedListItems>
            <HeadPointer>next</HeadPointer>
            <NextPointer>next</NextPointer>
            <ValueNode>($T1 *)this</ValueNode>
        </LinkedListItems>
    </Expand>
</Type>

リスト ヘッドと比較する NextPointer に Condition 属性を追加できることを期待しましたが、NextPoint はノードのコンテキストで評価されるため、何と比較すればよいかわかりません。

<NextPointer Condition="next!=XXXXXXXXX">next</NextPointer>

これは、 #list がこれを自動的に処理していたため、skip ディレクティブを使用して、以前 (2010 年) のビジュアライザーでどのように見えたかを示しています。

#list無限のトラバーサルから保護され、循環リストに適切に対処します。また、skip:式を使用して、報告されるべきではないセンチネル ノードを示すこともできます。名前はノードがスキップされることを暗示していますが、実際にはトラバーサルが停止するため、センチネル ノードが最初にある場合は、その後にトラバーサルを開始する必要があります。

TListBidir<*,*,*>{
    children
    (
      #list(
        head: ((($T2 *)&$c)->next),
        next: next,
        skip : &($c)
      ): (($T1 *)(&$e))
    )
}

ルート要素に再び到達したら、リストの展開を停止する必要があるデバッガーに natvis で説明するにはどうすればよいですか?

4

3 に答える 3

3

循環リストではなく、最後にそれ自体を指すセンチネルノードで同様の問題があり、ニーズに適応できる興味深い解決策を思いつきました。三項演算子を使用して、実質終了。内部の式<NextPointer>は、vanilla C で記述できるものであれば何でもかまいません。そのため、そこで実際の計算を行うことができます (残念ながら、再帰はありません)。

Condition( に属性を設定することは許可されていないことに注意してください。その<NextPointer>ため、そこで条件を達成する唯一の方法は三項演算子です。)

したがって、私の場合、リストは次のように終了します。

<LinkedListItems>
    <HeadPointer>this</HeadPointer>
    <NextPointer>next != this ? next : 0</NextPointer>
    <ValueNode>items</ValueNode>
</LinkedListItems>

あなたの場合、ノードがそれぞれコンテナーへのポインターを持っている場合、それを使用してヘッド ノードと比較できます。

<LinkedListItems>
    <HeadPointer>container-&gt;head</HeadPointer>
    <NextPointer>next != container-&gt;head ? next : 0</NextPointer>
    <ValueNode>items</ValueNode>
</LinkedListItems>

または、&gt;エンティティがなく、より伝統的な C として記述されている場合、次と同等です。

next != container->head ? next : NULL

ただし、何らかのcontainerバックポインタがない場合は、循環リンク リスト内の 1 つのノードだけを見て、それが事実上「最後の"ノード。

于 2016-03-09T15:04:09.933 に答える
3

要素でこれを行うことができますCustomListItems

<CustomListItems>
    <Variable Name="orig_head" InitialValue="head"/>
    <Variable Name="iter" InitialValue="first_elem"/>
    <Loop>
        <Break Condition="iter == orig_head || iter == 0"/>
        <Item>*iter</Item>
        <Exec>iter = iter-&gt;next_elem</Exec>
    </Loop>
</CustomListItems>

CustomListItemsリストをトラバースしながら使用できるように、変数にヘッドを保存できます。頭のタイプがリスト ノードと異なる場合は、それをノード タイプにキャストする必要があります。

于 2016-08-22T16:20:40.383 に答える
2

natvis フレームワークは現在、カウントが指定されていない循環リンク リストをサポートしていません。カウントを指定すると、機能するはずです。ただし、カウントがなければ、拡張が永遠に続くのを防ぐ良い方法はありません。

于 2012-08-15T20:09:19.907 に答える