我正在尝试实现一个分段树,每当我尝试调用下面的 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/