c++ - 由 ref 传递给函数的 vector 自动取消分配

标签 c++ c++11 gdb

我正在尝试实现一个分段树,每当我尝试调用下面的 queryST(...) 函数时,它都会抛出一个段错误,因为它无法访问输入 vector st 了。 下面的 vector st 是通过 buildSt(...) 正确填充的,但是每当函数 queryST(...) 被调用时,它就是抛出段错误。 代码分享如下。

我试过使用 GDB 进行调试,它显示了很多类似的回溯,例如:

程序收到信号 SIGSEGV,段错误。 查询ST中的0x0000555555554de1 (st=..., v=0, L=0, R=0, l=2, r=3) at segtree.cpp:30 30 返回查询ST(st, 2*v, L, mid, l, r) + queryST(st, 2*v+1, mid+1, R, l, r);

此外,当我尝试在 GDB 中为上述帧打印 vector st 时,它说 它无法访问地址处的内存 ...

vector st 自动解除分配或它的内存不再可访问,正在由 GDB 结束。

查询ST(...)

int queryST(vector<int>& st, int v, int L, int R, int l, int r) {

    if(l > R && r < L)
      return 0;

    if(l <= L && r >= R)
      return st[v];
    int mid = (L + R) / 2;

    return  queryST(st, 2*v, L, mid, l, r) + queryST(st, 2*v+1, mid+1, R, l, r);
 }

主要(...)

int main() {
   ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);

   vector<int> a({1,2,-3, 8, 9});
   vector<int> st(a.size()*4 + 1);
   buildST(st, a, 1, 0, 4);
   //cout << st[1] << endl;
   cout << queryST(st, 1, 0, 4, 2, 3) << endl;
   return 0;
 }

更新ST(...)

void buildST(vector<int>& st, vector<int>& a, int v, int L, int R) {                                      
   if(L == R) {
      st[v] = a[L];
      return;
   }
    if(L < R) {
      int mid = (L+R)/2;
      buildST(st, a, 2*v, L, mid);
      buildST(st, a, 2*v+1, mid+1, R);
      st[v] = st[2*v] + st[2*v+1];
    } 
  }

预期结果应该是查询range[2,3]对应于queryST(...)的参数5th和6th的答案

谢谢。

最佳答案

But I still can't think of "why gdb couldn't access the vector st inside queryST() "

GDB 使用调试信息访问变量。

为了打印st,GDB需要找到指向它的指针。调试信息告诉 GDB,指向 st 的指针在堆栈上,与 $rsp$rbp 寄存器有一定的偏移量。当 GDB 试图读取该内存时(通过 ptrace 系统调用),ptrace 返回一个错误(因为 $rsp 指向不可读的内存,因为堆栈溢出)。因此你会得到 cannot access memory at address ... 错误。

如果您查看实际地址,您会发现它就在页面边界下方,并且它上面的页面是可读的,并且是堆栈的最后一页。

关于c++ - 由 ref 传递给函数的 vector 自动取消分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57445671/

相关文章:

c++ - 我的复制构造函数有什么问题?

c++ - 如何 `decltype` 仿函数运算符()?

c++ - 奇怪的段错误

c++ - 类模板的静态成员初始化

c++ - 为什么在变量中存储右值引用会导致它悬空

c++ - 将参数传递给 boost::thread 没有重载函数需要 2 个参数

c++ - 访问指针句柄中对象的地址

c++ - ClangOnWin 是一个可靠的发行版吗?

c++ - GDB 和 C++ : Printing vector of pointers to objects

gdb - lldb 的 'info frame' 是什么?