stack pop() 导致“引用绑定到未对齐的地址”错误
Posted
技术标签:
【中文标题】stack pop() 导致“引用绑定到未对齐的地址”错误【英文标题】:stack pop() causes "reference binding to misaligned address" error 【发布时间】: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。它不仅经常使事情变得更糟,而且如果问题确实消失了,它会更难准确地确认您为解决问题所做的工作。如果您不知道修复是什么以及它为什么起作用,那么您可能只是隐藏了问题并移到了它出现的地方。
【参考方案1】:
这不是上述答案中的参考 - 您需要参考才能实际更改 st.如果您不将 v 声明为引用,您最终只会在本地对 v 进行更改,而不是对 st 进行更改。
使用 leetcode 中的示例,在所有推送之后,st[3]
应该有一个包含[5]
的堆栈。在第一次弹出时,该堆栈不为空,因此我们将其弹出。所以st[3]
应该是一个空栈。然后在下一次pop中,v = st.begin() -> 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<int>&v=st.begin()->second;
这里可能有问题,也许尝试在不使用参考的情况下实现你的算法。
从技术上讲,我猜您将指针引用到尚不存在的内存的一部分,并且您正在获得一个 UB,因为您将继续阅读错误。
如果您删除&
,您会发现您的代码没有错误。但是,它会输出部分错误的结果。
除此之外,我们还可以使用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.【讨论】:
“可能这里有问题”的答案并不让人放心。那行代码当然是一个危险信号,但这不足以解释错误。 我不能。那条线是一个危险信号,但我没有看到任何不正确的地方。以上是关于stack pop() 导致“引用绑定到未对齐的地址”错误的主要内容,如果未能解决你的问题,请参考以下文章