簡體   English   中英

如何訪問調用堆棧?

[英]How to access the call stack?

我有一個由父節點和子節點組成的樹數據結構,如下所示:

<Node1>
  <Node2/>

  <Node3>
    <Node4/>
  </Node3>
</Node1>

要解析結構,我使用μ遞歸函數:

void RecursiveFunction(NodeT node)
{
    if(node.has_child())
        RecursiveFunction(node.child());
}

當我調用RecursiveFunction作為參數傳遞時,例如,Node2我希望能夠訪問父(Node1)數據而不使用其他數據結構存儲這些數據,因為第一個節點的數據在制作之前已經存儲在調用堆棧中遞歸調用。 因此,當我解析Node2無法直接訪問父親時,我需要訪問調用堆棧以讀取Node1的數據,依此類推。

例如,如果我正在解析Node4:

void RecursiveFunction(NodeT node)
{
    /* Access to Node3 and Node1 data...

    if(Node4.has_child())
        RecursiveFunction(Node4.child()); */
}

可能嗎? 以什么方式?

謝謝。

這是可能的,但這樣做會非常危險。 這主要是因為你想搞亂進程堆棧。 另外我不認為有任何庫函數可以這樣做,據說你必須做一些指針算術來實現這一點。

即使您找到了一種從調用函數訪問數據的方法,任何其他程序員都不容易理解您的操作。

我建議通過迭代替換遞歸,這應該允許您清楚地表達您想要做的事情。 有關更多信息,請參閱從遞歸到迭代的方法。

訪問callstack對我來說有點過度工程。 將函數從遞歸轉換為迭代並使用您自己的堆棧。 堆棧應包含一個NodeT實例和通知函數的整數值,已經處理了多少個節點的子節點。 如果此值低於節點的子計數,則循環將遞增此值並將下一個子項添加到堆棧。 否則它將處理節點,然后從堆棧中彈出它。

另一個優點是,您不再受程序堆棧大小的限制,並且如果有這樣的需要,您可以處理更多嵌套結構。 否則你冒險,好吧,讓我們不要害怕說,堆棧溢出。

如果您想要或必須(例如家庭作業?)堅持遞歸,請將父節點作為第二個參數添加到您的函數中,默認為NULL ,表示當前節點是根節點。 即:

void RecursiveFunction(NodeT const& node, NodeT const* parentPtr=NULL)
{
    if(node.has_child())
        RecursiveFunction(node.child(), &node);
}

請注意,我修改了您的函數以通過引用const接受第一個參數,否則您將創建樹的許多副本。

調用堆棧也用於函數參數*,因此使用它來構建鏈:

struct chain {
  NodeT* node;
  chain const* parent;
}
void RecursiveFunction(chain const& c)
{
    if(c.node->has_child()) {
       chain child = { c.node->child(), &c };
        RecursiveFunction(child);
    }
}

[*]至少在概念上; 實際實施可能不同。 無論如何,這個C ++代碼是可移植的,與低級別的黑客不同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM