-1

I am getting error Exception thrown at 0x009523B9 in Project5.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x00E42ED4). in the below program

test case:

5

1 2 3 4 5

1

Q 2 4

I was getting error when executing this line struct node query(int index, int start, int endv, int l, int r) that is when query function was called for first time in main

The parameter were like at the time of exception thrown should be query(0,0,4,1,3)

but they are automatically changing to query(0,1,1,1,3) where I am doing wrong

This was the question based on segment trees spoj KGSS

#include<iostream>
#include<algorithm>
#include<climits>
#pragma warning(disable:4996)    //disable scanf warning 
using namespace std;

struct node {
    long long int maxsum;
    long long int maxnum;
};
long long int a[100];
struct node tree[100];
void build(int index, int start, int endv) {
    if (start == endv) {
        tree[index].maxsum = a[start];
        tree[index].maxnum = a[start];
    }
    else {
        int mid = (start + endv) / 2;
        build(2 * index + 1, start, mid);
        build(2 * index + 2, mid + 1, endv);

        tree[index].maxnum = max(tree[2 * index + 1].maxnum, tree[2 * index + 2].maxnum);
        tree[index].maxsum = max(tree[2 * index + 1].maxnum + tree[2 * index + 2].maxnum, max(tree[2 * index + 1].maxsum, tree[2 * index + 2].maxsum));
    }
}

struct node query(int index, int start, int endv, int l, int r) {

    struct node result;

    result.maxnum = INT_MIN;
    result.maxsum = INT_MIN;

    if (l > endv || r < start)
        return result;
    int mid = (start + endv) / 2;
    struct node left, right;
    left = query(index, start, mid, l, r);
    right = query(index, mid + 1, endv, l, r);

    tree[index].maxnum = max(left.maxnum, right.maxnum);
    tree[index].maxsum = max(left.maxnum + right.maxnum, max(left.maxsum, right.maxsum));

    return tree[index];
}

void update(int index, int start, int endv, int aidx, long long int value) {


    if (start == endv) {
        a[aidx] = value;
        tree[index].maxsum = value;
        tree[index].maxnum = value;
    }
    else {

        int mid = (start + endv) / 2;
        if (aidx <= mid) {
            update(2 * index + 1, start, mid, aidx, value);
        }
        else {
            update(2 * index + 2, mid + 1, endv, aidx, value);
        }

        tree[index].maxnum = max(tree[2 * index + 1].maxnum, tree[2 * index + 2].maxnum);
        tree[index].maxsum = max(tree[2 * index + 1].maxnum + tree[2 * index + 2].maxnum, max(tree[2 * index + 1].maxsum, tree[2 * index + 2].maxsum));
    }
}

int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    build(0, 0, n - 1);
    //for(int i = 0)
    int q;
    cin >> q;
    for (int i = 0; i < q; i++) {
        int l, r;
        char ap;
        cin >> ap >> l >> r;
        if (ap == 'U') {
            update(0, 0, n - 1, l - 1, r);
        }
        else {
            struct node temp = query(0, 0, n - 1, l - 1, r - 1);
            printf("%lld\n", temp.maxsum);
        }
    }

}

NOTE -> I used result.maxnum = INT_MIN; result.maxsum = INT_MIN;

in query function and result.maxnum and result.maxsum are of long long int types and i am assigning INT_MIN to them.

This is because some times from both side of the recursion i get min value and on adding these values and storing them on a int variable leads to integer overflow thats why i used long long int can someone provide way for handling this situation or this is ok

akacoders
  • 29
  • 3

1 Answers1

0
    scanf("%d", &a[i]);

is incorrect when the type of a[i] is long long int. It's also not a good idea to mix C++ I/O with C I/o. There's nothing wrong with

cin >> a[i];

But the main problem is that you have a stack overflow. In your example

query(0,0,4,1,3) ->
 query(0,0,2,1,3) ->
  query(0,0,1,1,3) ->
   query(0,0,0,1,3) ->
    return result
   query(0,1,1,1,3) ->
    query(0,1,1,1,3) ->
     query(0,1,1,1,3) ->
      query(0,1,1,1,3) ->
       query(0,1,1,1,3) ->
        query(0,1,1,1,3) ->
         query(0,1,1,1,3) ->
          BOOM!! stack overflow

Not quite sure what to do to fix it, since I don't understand the code. I would have thought something like

if (start >= endv)
    return result;

at the beginning would help but I'm not really sure.

john
  • 85,011
  • 4
  • 57
  • 81
  • _"Not quite sure what to do to fix it"_ The obvious solution is to use a `std::stack` with an appropriate structure to represent the parameters. Any recursion can be replaced that way. – πάντα ῥεῖ Jan 27 '19 at 09:09
  • @πάνταῥεῖ But then you'd just replace the stack overflow with memory exhaustion. My point was that the algorithm needs to change because it's infinitely recursive, but I'm not sure how to do that. – john Jan 27 '19 at 09:22
  • There's many more dynamic memory available than on the stack. If there's a proper condition to stop the recursion at all, `std::stack` would bring you far further. – πάντα ῥεῖ Jan 27 '19 at 09:24
  • @πάνταῥεῖ The point (my point) is that there isn't a proper condition at the moment. Until that's corrected using `std::stack` is not a solution. – john Jan 27 '19 at 09:28
  • But My program terminates to the first call to `query()` I noted that while debugging ,how compiler is sure itself that recursion will go infinitely without executing the full code – akacoders Jan 27 '19 at 09:34
  • @akacoders I think you're mistaken. When I tested your program it terminated with a stack overflow when the variables had the values that you said they 'automatically' changing to. They're not automatically changing, they changing because of recursive calls. – john Jan 27 '19 at 13:46