简体   繁体   English

由于C ++程序结尾处的malloc而导致段错误

[英]Seg Fault due to malloc at the end of C++ program

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: 在GDB中执行运行时的错误消息是:

Program received signal SIGSEGV, Segmentation fault. 程序收到信号SIGSEGV,分段故障。 0x00007ffff71f0532 in __GI___libc_free (mem=0x617c60) at malloc.c:2967 2967 malloc.c: No such file or directory. __GI___libc_free(mem = 0x617c60)中的0x00007ffff71f0532,位于malloc.c:2967 2967 malloc.c:无此类文件或目录。

On backtracing with GDB, the problem seems to originate at the line at the beginning of main function declaring vector nums. 在使用GDB回溯时,问题似乎出在声明向量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. 我也尝试使用Valgrind,但一无所知。

The code (in C++) is: 代码(在C ++中)是:

#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;
}

Look at this function 看这个功能

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];
}

that calls it self recursively. 自我递归地调用它。

Now add this cout at the start of the function, like: 现在,在函数开始时添加此cout ,例如:

int constructSTUtil(vector<int> nums,int ss, int se, int* st,int si)
{
    cout << "ss = " << ss << " se = " << se << " si = " << si << endl;

When nums have 5 elements this will give you: nums有5个元素时,这将为您提供:

ss = 0 se = 4 si = 0
ss = 0 se = 2 si = 1
ss = 0 se = 1 si = 3
ss = 0 se = 0 si = 7
              ^^^^^^
              ups... out of range for `st`

So when you do: 因此,当您这样做时:

st[si] = nums[ss];

You are writing out of bounds. 您正在写书。 In other words, there is something wrong with your algorithm. 换句话说,您的算法有问题。

BTW: 顺便说一句:

int stSize = 2*(int)pow(2,height)-1;
     ^^^^^
     Never used in the code

Also it seems rather confusing that you have a member st and also function argument st . 还有一个成员st和函数参数st似乎也很令人困惑。 And it's also confusing that you assign to st using the return value from constructsST (which is st ). 而且,使用constructsST (即st )的返回值分配给st做法也令人困惑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM