0

I am a beginner in CPP problem solving and am having trouble with this question:- Q)Given an unsorted array of nonnegative integers, find a continuous subarray that adds to a given number. I am debugging it with gdb and getting no output and it's showing process exited normally inferior 1. Any suggestions as to why it's happening?

#include <stdio.h>
#include<iostream>
#include<vector>
using namespace std;
void subarray(vector<int> &a,int s,int n);
int main() {
    int t,n,s,x;
    cin>>t;
    vector<int> v;
    while(t)
    {
        cin>>n>>s;
        for(int i=0;i<n;i++)
        {  
            cin>>x;
            v.push_back(x);
        }
        subarray(v,s,n);
        t--;
        v.clear();
    }
    return 0;
}
void subarray(vector<int> &a,int s,int n)
{
    int j,sum,i=0;
    while(j<n&&i<n)
    {
        sum+=a[j];
        if(sum>s)
        {
            sum=sum-a[i];
            i++;
            j=i;
        }
        if(sum<s)
        {
          j++;  
        }
        else
        {
            cout<<i+1<<" "<<j+1<<endl;
            break;
        }
        if(j==n&&i<n)
        {
          i++;
          j=i;
        }
        if(j==n&&i==n)
        {
            cout<<-1<<endl;
            break;
        }
       
    }
    

}
lets_code
  • 23
  • 6
  • 2
    Debuggers don't find bugs. They help you find bugs. What you want to do is use the debugger to step through the program line by line and see where the program's behaviour deviates from what you expected. The unexpected is almost always a bug. – user4581301 Dec 21 '20 at 06:11
  • I guess it's because you have this line in your subarray method ```int j,sum,i=0;``` it means ```int j; int sum; int i=0;```. And after you try to get value from vector with wrong index ```sum+=a[j];```. I think this is not what you want. If you want to init several variables in one line do it like this ```int a = 0, b = 0, c = 0, d = 0;``` or ```int a = 0, b = a, c = a, d = a;```. – Anton Shwarts Dec 21 '20 at 06:20
  • `int j,sum,i=0;` where `j` in **uninitialized** in the first calls to `while(j – David C. Rankin Dec 21 '20 at 06:27

1 Answers1

1

Your immediate problem is in subarray() where j and sum are uninitialized after int j,sum,i=0; so on your first loop iteration, You invoke Undefined Behavior when you attempt to access each variable when its value is indeterminate. That includes:

    int j,sum,i=0;
    while(j<n&&i<n)
    {
        sum+=a[j];    /* likely SegFaults when index is wildly outside vector bounds */

In gdb, your code is executing withing gdb's own protected memory space so you may avoid the segfault there while it would likely segfault when run outside of gdb.

All of these problems would have been caught if you had simply compiled with Warnings Enabled. Always compile with warnings enabled, and do not accept code until it compiles without warning. To enable warnings add -Wall -Wextra -pedantic to your gcc/clang compile string (also consider adding -Wshadow to warn on shadowed variables). For VS (cl.exe on windows), use /W3. All other compilers will have similar options. Read and understand each warning -- then go fix it. They will identify any problems, and the exact line on which they occur.

Don't leave your user staring at a blinking cursor on the screen wondering if your program is hung. Prompt the user for input so they have some inkling of what is expected. Then validate EVERY user-input and ensure the value provided is within any needed range. Fixing the immediate issues to avoid the undefined behavior, validating all user-input, and providing additional suggestions as comments below, you would have:

// #include <stdio.h>   /* do not include unnecessary headers */
#include <iostream>
#include <vector>

void subarray (std::vector<int> &a,int s,int n);

int main (void) {
    
    int t;
    
    std::cout << "enter value for t: ";     /* prompt */
    if (!(std::cin>>t)) {   /* validate EVERY user-input */
        std::cerr << "error: invalid integer input 't'.\n";
        return 1;
    }
    if (t < 1) {    /* valid EVERY value is within a valid range (if applicable) */
        std::cerr << "error: integer must be greater than 1.\n";
        return 1;
    }
    
    std::vector<int> v{};   /* brace initialize object as empty */
    
    while (t)               /* loop t times */
    {
        int n, s;           /* declare variables in the scope needed */
        
        std::cout << "\nenter values for n & s: ";
        if (!(std::cin >> n >> s)) {    /* validate EVERY user-input */
            std::cerr << "error: invalid integer input 'n', 's'.\n";
            return 1;
        }
        if (n < 1) {    /* valid EVERY value is within a valid range (if applicable) */
            std::cerr << "error: integer must be greater than 1.\n";
            return 1;
        }
        /* same for s */
        
        for (int i = 0; i < n; i++)
        {  
            int x;                  /* declare in scope */
            
            std::cout << "  v[" << i << "]: ";
            if (std::cin >> x)      /* validate */
                v.push_back(x);     /* add to vector */
        }
        subarray (v, s, n);
        
        t--;
        v.clear();
    }
}

void subarray (std::vector<int> &a, int s, int n)
{
    int j = 0, sum = 0, i = 0;      /* initialize all values */
    while (j < n && i < n) {
        sum += a[j];
        
        if (sum > s) {
            sum = sum - a[i];
            i++;
            j = i;
        }
        else if (sum < s) {
            j++;  
        }
        else {
            std::cout << i+1 << " " << j+1 << '\n';
            break;
        }
        
        if (j == n) {
            if (i < n) {
                i++;
                j = i;
            }
            if (i == n) {
                std::cout << -1 << '\n';
            }
        }
    }
}

Your code will now compile without warning -- but you must confirm the logic of your code. That is left to you.

Example Use/Output

Adding the prompts, your program provides the following output:

$ ./bin/subarraychk
enter value for t: 3

enter values for n & s: 3 4
  v[0]: 8
  v[1]: 2
  v[2]: 6
-1

enter values for n & s: 4 1
  v[0]: 0
  v[1]: 2
  v[2]: 3
  v[3]: 4
-1

enter values for n & s: 5 3
  v[0]: 2
  v[1]: 4
  v[2]: 6
  v[3]: 8
  v[4]: 10
-1

As mentioned in the comment above, using namespace std; was removed. See Why is “using namespace std;” considered bad practice? and the use of endl was replaced with a simple '\n', see: C++: “std::endl” vs “\n” The code spacing was also improved to make the code more readable (which may help you find any logic or syntax errors as well)

Let me know if you have further questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85