You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

错误原因分析

  1. 栈空时执行pop操作:代码处理指令2(pop)时未检查栈是否为空。测试输入中,连续两次执行push+pop操作后栈变为空,后续的pop操作会破坏栈的内部结构,导致后续push时触发内存非法访问,引发Segmentation fault。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 23:27:45