【问题标题】:stack pop() causes "reference binding to misaligned address" errorstack pop() 导致“引用绑定到未对齐的地址”错误
【发布时间】:2020-08-07 21:03:30
【问题描述】:

我正在尝试为这个 leetcode 问题编写解决方案https://leetcode.com/problems/maximum-frequency-stack/

class FreqStack {
public:
    
   
    map<int, int>mp;
    map<int, stack<int>, greater<int>>st;
    FreqStack() {
        
    }
    
    void push(int x) {
        mp[x]++;
        st[mp[x]].push(x);
        
       
    }
    
    int pop() {
        stack<int>&v=st.begin()->second;
        
        int t=v.top();
        
        
        if(!v.empty()){
        v.pop();
        }
        else{
            st.erase(st.begin());
        }
       
        return t;
    }
};

为什么

v.pop()

导致“引用绑定到未对齐的地址”错误?

【问题讨论】:

  • 这似乎无关,但您在假设堆栈不为空之后检查堆栈是否为空。
  • 是的,我知道我只是在尝试不同的方法,看看是否可以让错误消失
  • 调用代码是做什么的? .push(0) 然后是 .pop() 也不是 _GLIBCXX_DEBUG 的地址清理程序我什么也没得到。
  • 恐惧shotgun debugging。它不仅经常使事情变得更糟,而且如果问题确实消失了,它会更难准确地确认您为解决问题所做的工作。如果您不知道修复是什么以及它为什么起作用,那么您可能只是隐藏了问题并移到了它出现的地方。

标签: c++ dictionary vector stack


【解决方案1】:

这不是上述答案中的参考 - 您需要参考才能实际更改 st.如果您不将 v 声明为引用,您最终只会在本地对 v 进行更改,而不是对 st 进行更改。

使用 leetcode 中的示例,在所有推送之后,st[3] 应该有一个包含[5] 的堆栈。在第一次弹出时,该堆栈不为空,因此我们将其弹出。所以st[3] 应该是一个空栈。然后在下一次pop中,v = st.begin() -&gt; second会返回这个空栈,所以pop/top失败。这就是为什么评论流行语或使 v 不是参考在解决问题方面有效,但实际上并没有做任何功能方面的事情。

您需要做的是:弹出后,如果它是一个空堆栈,您需要从 st.所以你的弹出代码看起来像这样

    stack<int>&v=st.begin()->second;
    
    int t=v.top();
    
    
    if(!v.empty()){
    v.pop();
    }

    if (v.empty()) {
        st.erase(st.begin());
    }
   
    return t;

我所做的唯一更改是将 else 变成 if。我希望在 v 不是空的情况下有 t = v.top() ,但是由于我们在堆栈为空时删除频率,所以我们应该被覆盖(v 永远不应该为空)。那应该可以解决您的问题-但这不是 leetcode 问题的正确答案。让你自己弄清楚。

【讨论】:

    【解决方案2】:

    stack&lt;int&gt;&amp;v=st.begin()-&gt;second; 这里可能有问题,也许尝试在不使用参考的情况下实现你的算法。

    从技术上讲,我猜您将指针引用到尚不存在的内存的一部分,并且您正在获得一个 UB,因为您将继续阅读错误。

    如果您删除&amp;,您会发现您的代码没有错误。但是,它会输出部分错误的结果。


    除此之外,我们还可以使用unordered_map

    这将通过:

    // This block might trivially optimize the exec time;
    // Can be removed;
    static const auto __optimize__ = []() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(NULL);
        return 0;
    }();
    
    
    // Most of headers are already included;
    // Can be removed;
    #include <cstdint>
    #include <unordered_map>
    #include <stack>
    #include <algorithm>
    
    static const struct FreqStack {
        using SizeType = std::uint_fast32_t;
        FreqStack() {}
        std::unordered_map<SizeType, SizeType> frequencies;
        std::unordered_map<SizeType, std::stack<SizeType>> mapstack;
        SizeType max_fr = 0;
    
        const void push(const int x) {
            max_fr = std::max(max_fr, ++frequencies[x]);
            mapstack[frequencies[x]].push(x);
        }
    
    
        const int pop() {
            const auto top = mapstack[max_fr].top();
            mapstack[max_fr].pop();
    
            if (mapstack[frequencies[top]--].empty()) {
                --max_fr;
            }
    
            return top;
        }
    
    };
    
    

    参考文献

    • 更多详细信息,请参阅Discussion Board,您可以在其中找到大量解释清楚且公认的解决方案,其中包含多种languages,包括高效算法和渐近time/space 复杂性分析1,2.

    【讨论】:

    • “可能这里有问题”的答案并不让人放心。那行代码当然是一个危险信号,但这不足以解释错误。
    • 我不能。那条线是一个危险信号,但我没有看到任何不正确的地方。
    猜你喜欢
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 2012-09-08
    • 2015-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多