The program uses Segment Trees to find the sum of given range query. It gives the correct answers to the input enterred. However, at the end of the program after executing all lines from the main function, it displays a segmentation fault. Link to image of the output screen.
The error message on executing run in GDB is:
Program received signal SIGSEGV, Segmentation fault. 0x00007ffff71f0532 in __GI___libc_free (mem=0x617c60) at malloc.c:2967 2967 malloc.c: No such file or directory.
On backtracing with GDB, the problem seems to originate at the line at the beginning of main function declaring vector nums. But I can't see what's wrong with my code. The code involving segment trees seems to be fine. I tried using Valgrind too, but couldn't understand anything.
The code (in C++) is:
#include <bits/stdc++.h>
using namespace std;
class NumArray
{
public:
int* st;
vector<int> nums;
NumArray(vector<int> num)
{
st = new int[num.size()];
if(num.size() != 0)
{
st = constructST(num);
}
nums = num;
}
int* constructST(vector<int> nums)
{
int height = ceil(log(nums.size())/log(2));
int stSize = 2*(int)pow(2,height)-1;
constructSTUtil(nums,0,nums.size()-1,st,0);
return st;
}
int constructSTUtil(vector<int> nums,int ss, int se, int* st,int si)
{
if(ss == se)
{
st[si] = nums[ss];
return st[si];
}
int mid = ss + (se-ss)/2;
st[si] = constructSTUtil(nums,ss,mid,st,2*si+1) + constructSTUtil(nums,mid+1,se,st,2*si+2);
return st[si];
}
void update(int i, int val)
{
int diff = val - nums[i];
nums[i] = val;
int n = nums.size();
updateUtil(st,0,n-1,i,diff,0);
}
void updateUtil(int* st,int ss,int se,int i,int diff,int si)
{
if(i < ss || i > se)
{
return;
}
st[si] = st[si] + diff;
if(se != ss)
{
int mid = ss + (se-ss)/2;
updateUtil(st,ss,mid,i,diff,2*si+1);
updateUtil(st,mid+1,se,i,diff,2*si+2);
}
}
int sumRange(int i, int j)
{
int n = nums.size();
if(i < 0 || i > j || j > n)
{
cout << "Invalid input";
return -32768;
}
return sumRangeUtil(st,0,n-1,i,j,0);
}
int sumRangeUtil(int* st,int ss, int se, int qs, int qe, int si)
{
if(qs <= ss && qe >= se)
{
return st[si];
}
if(qs > se || qe < ss)
{
return 0;
}
int mid = ss + (se-ss)/2;
return sumRangeUtil(st,ss,mid,qs,qe,2*si+1) + sumRangeUtil(st,mid+1,se,qs,qe,2*si+2);
}
};
int main()
{
vector<int> nums;
nums.push_back(0);
nums.push_back(9);
nums.push_back(5);
nums.push_back(7);
nums.push_back(3);
NumArray obj(nums);
cout << obj.sumRange(4,4) << "\n";
cout << obj.sumRange(2,4) << "\n";
cout << obj.sumRange(3,3) << "\n";
obj.update(4,5);
obj.update(1,7);
obj.update(0,8);
cout << obj.sumRange(1,2) << "\n";
obj.update(1,9);
cout << obj.sumRange(4,4) << "\n";
cout << obj.sumRange(3,4) << "\n";
return 0;
}