C++代码中unordered_map与stack引发Segmentation fault问题排查
栈操作代码段错误(Segmentation Fault)排查
问题背景
这段C++代码实现了栈的push(指令1)、pop(指令2)、查询最大值(指令3)功能,通过unordered_map以栈的大小为键存储对应栈状态的最大值。运行时触发Segmentation fault,GDB调试显示错误出现在my_stack.push(num_to_push)行。
待排查代码
#include <climits> #include <iostream> #include <stack> #include <string> #include <unordered_map> #include <vector> int main() { int n; std::cin >> n; std::vector<std::string> operations(n); std::cin.ignore(); for (int i = 0; i < n; i++) { getline(std::cin, operations[i]); } std::unordered_map<int, int> my_map; std::stack<int> my_stack; my_map[0] = INT_MIN; for (int i = 0; i < n; i++) { std::string query = operations[i]; if (!query.empty()) { if (query[0] == '1') { query.erase(0, 2); int num_to_push = stoi(query); my_stack.push(num_to_push); int size = my_stack.size(); if (my_map[size - 1] < num_to_push) my_map[size] = num_to_push; else my_map[size] = my_map[size - 1]; } if (query[0] == '2') { my_stack.pop(); } if (query[0] == '3') { int size = my_stack.size(); std::cout << my_map[size] << "\n"; } } } return 0; }
GDB调试输出
Starting program: /home/oddity/aa/test < input.txt Program received signal SIGSEGV, Segmentation fault. 0x0000555555558f34 in __gnu_cxx::new_allocator<int>::construct<int, int const&> ( this=0x7fffffffdf90, __p=0x1fc) at /usr/include/c++/9/ext/new_allocator.h:146 146 { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } (gdb) backtrace #0 0x0000555555558f34 in __gnu_cxx::new_allocator<int>::construct<int, int const&> ( this=0x7fffffffdf90, __p=0x1fc) at /usr/include/c++/9/ext/new_allocator.h:146 #1 0x0000555555558106 in std::allocator_traits<std::allocator<int> >::construct<int, int const&> (__a=..., __p=0x1fc) at /usr/include/c++/9/bits/alloc_traits.h:483 #2 0x00005555555581a2 in std::deque<int, std::allocator<int> >::_M_push_back_aux<int const&> (this=0x7fffffffdf90) at /usr/include/c++/9/bits/deque.tcc:496 #3 0x000055555555774b in std::deque<int, std::allocator<int> >::push_back ( this=0x7fffffffdf90, __x=@0x7fffffffdf1c: 26) at /usr/include/c++/9/bits/stl_deque.h:1579 #4 0x00005555555570cf in std::stack<int, std::deque<int, std::allocator<int> > >::push (this=0x7fffffffdf90, __x=@0x7fffffffdf1c: 26) at /usr/include/c++/9/bits/stl_stack.h:234 #5 0x00005555555566a8 in main () at /home/oddity/aa/test.cpp:25
测试输入
10 1 97 2 1 20 2 1 26 1 20 2 3 1 91 3
错误原因分析
- 栈空时执行pop操作:代码处理指令2(pop)时未检查栈是否为空。测试输入中,连续两次执行push+pop操作后栈变为空,后续的pop操作会破坏栈的内部结构,导致后续push时触发内存非法访问,引发Segmentation fault。
unordered_map数据不同步:执行pop后未清理my_map中对应栈大小的键值,虽不是直接引发段错误的原因,但会导致查询最大值时返回错误数据。
修复方案
修改后的代码
#include <climits> #include <iostream> #include <stack> #include <string> #include <unordered_map> #include <vector> int main() { int n; std::cin >> n; std::vector<std::string> operations(n); std::cin.ignore(); for (int i = 0; i < n; i++) { getline(std::cin, operations[i]); } std::unordered_map<int, int> my_map; std::stack<int> my_stack; my_map[0] = INT_MIN; for (int i = 0; i < n; i++) { std::string query = operations[i]; if (!query.empty()) { if (query[0] == '1') { query.erase(0, 2); int num_to_push = stoi(query); my_stack.push(num_to_push); int size = my_stack.size(); if (my_map[size - 1] < num_to_push) my_map[size] = num_to_push; else my_map[size] = my_map[size - 1]; } if (query[0] == '2') { // 检查栈是否为空,避免非法pop if (!my_stack.empty()) { int size_before = my_stack.size(); my_stack.pop(); // 清理map中不再需要的键值,保持数据一致性 my_map.erase(size_before); } } if (query[0] == '3') { int size = my_stack.size(); std::cout << my_map[size] << "\n"; } } } return 0; }
关键修改点
- 处理指令2时,先判断
my_stack.empty(),仅在栈非空时执行pop操作,避免破坏栈结构。 - 执行pop后,从
my_map中删除对应栈大小的键值,减少内存占用并保持数据一致性。
内容的提问来源于stack exchange,提问作者Vedant Yadav
相关产品推荐
相关产品推荐

