我已尝试在gdb中执行以下代码,但是使用gdb我没有看到任何分段错误但没有gdb如果我在独立模式下运行以下代码,则会发生分段错误。该代码与使用分段树实现的范围和查询相关。
#include <iostream>
#include <vector>
using namespace std;
class segmentTree
{
private:
vector<int> a;
void constructUtil(vector<int>& , int , int , int );
int queryUtil(int , int , int , int , int );
void updateUtil(int , int , int , int , int );
public:
segmentTree(vector<int> );
int query(int , int );
void update(int , int );
~segmentTree();
};
segmentTree::segmentTree(vector<int> v)
{
int n = v.size();
a.resize((2*n) - 1);
constructUtil(v, 0 , n - 1, 0);
}
segmentTree::~segmentTree()
{
a.clear();
}
void segmentTree::constructUtil(vector<int>& v, int start, int end, int i)
{
if(start == end)
{
a[i] = v[start];
}
else
{
int mid = start + ((end - start) >> 1);
constructUtil(v, start, mid, ((2*i) + 1));
constructUtil(v, mid + 1, end, ((2*i) + 2));
a[i] = a[(2*i) + 1] + a[(2*i) + 2];
}
}
int segmentTree::queryUtil(int ss, int se, int rs, int re, int i)
{
if(se < rs || re < ss)
{
return 0;
}
else if(rs <= ss && se <= re)
{
return a[i];
}
else
{
int sm = ss + ((se - ss) >> 1);
return queryUtil(ss, sm, rs, re, 2*i + 1) + queryUtil(sm + 1, se, rs, re, 2*i + 2);
}
}
int segmentTree::query(int l, int r)
{
int n = ((a.size() + 1) >> 1);
if(l < 0 || r > n-1)
{
return 0;
}
return queryUtil(0, n-1, l , r, 0);
}
void segmentTree::updateUtil(int ss, int se, int i, int si, int x)
{
if(ss > i || se < i)
{
return ;
}
else if(ss == se)
{
a[si] = x;
}
else
{
int sm = ss + ((se - ss) >> 1);
updateUtil(ss, sm, i, (2*si) + 1, x);
updateUtil(sm + 1, se, i, (2*si) + 2, x);
a[si] = a[(2*si) + 1] + a[(2*si) + 2];
}
}
void segmentTree::update(int i, int x)
{
int n = ((a.size() + 1) >> 1);
if(i < 0 || i > n-1)
{
return ;
}
else
{
updateUtil(0, n-1, i, 0, x);
}
}
int main()
{
int arr[] = {1, 3, 5, 7, 9, 11};
int n = sizeof(arr)/sizeof(arr[0]);
vector<int> v(arr, arr + n);
segmentTree st(v);
// Print sum of values in array from index 1 to 3
cout << "Sum of values in given range = " << st.query(1, 3) << endl;
// Update: set arr[1] = 10 and update corresponding
// segment tree nodes
st.update(1, 10);
// Find sum after the value is updated
cout << "Updated sum of values in given range = " << st.query(1, 3) << endl;
return 0;
}
答案 0 :(得分:1)
使用segmentTree::constructUtil
考虑v.size() == 3
。然后在constructUtil
的初始通话中,您有start == 0
和end == 2
。
因此我们得到mid = 1
。
在第二次递归调用中,我们传递start = 1
,end = 2
和i = 2
。 start != end
因此else
已执行。
然而,在else
块a[(2*i)+2]
被访问(顺便说一下,那里不需要parantheses)。该索引为6
。
但是,如果你查看a
的大小,则会将其显示为2*n-1
。 2*3-1 = 5
,所以6
明显超出范围。
我不知道您对代码的意图是什么,但是存在未定义的行为。您可以通过使用valgrind之类的东西轻松捕获它,将a[...]
替换为a.at(...)
以进行调试,通过使用gdb逐步执行代码并实际跟踪所有变量(不需要是您的程序具有未定义行为的分段错误)或通过输入调试std::cout
语句,其中包含可能导致问题的可变内容。