Search code examples
c++arraysmultidimensional-arraystdoutstdin

C++ Variable-sized arrays using stdin and stdout


I'm trying to solve this problem on variable-sized arrays but I'm getting a compilation error. Not exactly sure where I went wrong.

Problem can be accessed in this PDF

My solution attempt is as follows:

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;


int main() {
    /* Enter your code here. Read input from STDIN. Print output to STDOUT */   
    int n,q,size,elem,index,smallindex;

    //input of n and q
    cin>>n>>q;

    //declare the array a 
    int* bigarr = new int[q];

    //assign the individual arrays to each element of the array a
    for (int i=0; i<n; ++i){
        //input of size of the individual array
        cin>>size;
        int* smallarr = new int[size];

        for (int j=0; j<size; ++j){
            smallarr[j] = cin>>elem;
        }
        bigarr[i] = smallarr;
    }

    //obtain index queries
    for (int k=0; k<n; ++k){
        cin>>index;
        cin>>smallindex;
        cout<<bigarr[index][smallindex];
    }

}

Solution

  • On this statement:

    bigarr[i] = smallarr;
    

    smallarr is an int* pointer, but bigarr is also an int*, ie an array of int, so bigarr[i] is a single int. You can't assign an int* pointer to an int value.

    If you want bigarr to be an array of pointers to other arrays, you need to declare bigarr as int** instead of int*, and then use new int*[q] to allocate it.

    int** bigarr = new int*[q];
    

    Also, on this statement:

    smallarr[j] = cin>>elem;
    

    The expression cin>>elem returns an istream& reference to cin, it does not return the int value read into elem, like you are expecting. So you can't use the result of that expression directly in the assignment to smallarr[j]. You will have to read elem and assign it to smallarr in separate statements:

    cin>>elem;
    smallarr[j] = elem;
    

    That said, note that your code is leaking all of the allocated arrays since there are no calls to delete[] anywhere. You need to add them:

    int** bigarr = new int*[q];
    ...
    for (int i=0; i<n; ++i){
        ...
        int* smallarr = new int[size];
        ...
        bigarr[i] = smallarr;
    }
    ...
    for (int i=0; i<n; ++i){
        delete[] bigarr[i]; // <-- here
    }
    delete[] bigarr; // <-- here
    

    Though, you really should be using std::vector instead of using new[]/delete[] manually at all (you already have #include <vector>):

    std::vector<std::vector<int> > bigarr(q);
    ...
    for (int i=0; i<n; ++i){
        ...
        std::vector<int> smallarr(size);
        for (int j=0; j<size; ++j){
            ...
            smallarr[j] = elem;
        }
        bigarr[i] = smallarr;
    
        /* alternatively:
        bigarr[i].resize(size);
        for (int j=0; j<size; ++j){
            ...
            bigarr[i][j] = elem;
        }
        */
    }
    

    I also see is that you are using q to allocate bigarr, but then you use n to loop through bigarr. You don't need two separate variables. Use either n or q for both tasks, and get rid of the other variable.

    Unless you really intend to allocate more slots then you want to fill in. In which case, your outer loop needs to ensure that it doesn't exceed both n and q:

    for (int i=0; (i<n) && (i<q); ++i){
    

    Or:

    for (int i=0; i<std::min(n,q); ++i){