Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

dynamicly creating an 2D array, but how come array is bigger than ...



  • i'm creating an array dynamicly, but it's bigger than should be!

    int arraySize = arr.size(); // vector contains 6 elements
        std::cout << "arraySize: " << arraySize << std::endl;
    int a[arraySize][2];
        std::cout << "array size " << sizeof(a[0]) << std::endl;
    

    resturns:

    arraySize: 6
    
    array size 8
    

    if i try too:

    std::cout << "array size " << sizeof(a) << std::endl;
    

    the size will return:

    48
    

    what am i missing here?


  • Moderators

    what am i missing here?

    You're mixing number of elements with number of bytes. sizeof is an operator that returns size of the object in bytes, not number of elements in an array.

    arraySize is the number of elements in array a, 6 in this case.
    sizeof(a[0]) is a size (in bytes) of the first element of array a. An element of array a is an array of two ints. Size of one int is 4 bytes so size of two ints is 8.
    sizeof(a) is the size (in bytes) of array a. There's 6*2=12 elements and each element is 4 bytes in size so the total is 48 bytes.

    Everything is as it should be.
    What number would you like to get exactly?



  • @Chris-Kawa

    for a start, the compiler tells there is a problem.

    error: variable-sized object may not be initialized
    

    i changed the code a bit.

    int arraySize = 0;
        arraySize = arr.size(); // arr = a vector
        std::cout << "arraySize: " << arraySize << std::endl;
    int a[arraySize][2] = { 0,0 }; // <--- the problem is here.
        std::cout << "array size " << sizeof(a[0]) << std::endl;
    

  • Moderators

    Well the error tells you what's wrong . Think about it - the array size is determined at runtime and you'r asking the compiler to initialize it. How is it suppose to know at compile time what size the array will be when you run the program?

    If you want it filled with zeros you need to write a loop that will set the zeros or use memset on the thing with the appropriate size.



  • @Chris-Kawa

    thnx,

    how it's done?
    how to resize the or create the array "dynamicly"?

    int arraySize = 0;
        arraySize = arr.size();
        std::cout << "arraySize: " << arraySize << std::endl;
    int a[1][2] = { {0,0} };
    for(int i = 0; 1 <arraySize; i++){ // warning: variable 'arraySize' used in loop condition not modified in loop body
        a[i][2] = { 0,0 };   // error: excess elements in scalar initializer
    }
    

  • Moderators

    How to resize the or create the array "dynamicly"?

    Use dynamic allocation i.e. new/delete, or, better yet, a container class that will do that for you, like std::vector:

    std::vector<std::array<int,2>> a;
    

    and then you can resize it and fill with zeros like this:

    a.resize(arraySize, {0,0});
    


  • @Chris-Kawa

    thnx for your aswer.
    https://en.cppreference.com/w/cpp/container/array
    doesn't say anything about a "resize" member.

    but i want to give it a try.

    i found this ...
    https://stackoverflow.com/questions/3749660/how-to-resize-array-in-c

    int size = 10;
    int* arr = new int[size];
    
    void resize() {
        size_t newSize = size * 2;
        int* newArr = new int[newSize];
    
        memcpy( newArr, arr, size * sizeof(int) );
    
        size = newSize;
        delete [] arr;
        arr = newArr;
    }
    

    sofar i have this ...

    int arraySize = 0;
        arraySize = arr.size();
        std::cout << "arraySize: " << arraySize << std::endl;
    
    int *a[1][2] = { {0,0} };
    
    size_t newSize = arraySize;
    
    int* newArr = new int[2];
    
    for(int i = 0; i <arraySize; i++){
        *newArr[i][2] = { 0,0 }; // error: subscripted value is not an array, pointer, or vector
        // or
        *newArr[i] = { 0,0 }; // error: indirection requires pointer operand ('int' invalid)
    
    }
    memcpy( newArr, a, arraySize * sizeof(int) );
    
    //size = newSize;
    delete [] a[1][2];
    a = newArr; /// error: array type 'int *[1][2]' is not assignable
    
    

  • Moderators

    doesn't say anything about a "resize" member.

    You can't resize an array and I'm not resizing an array. I'm resing a vector of arrays: https://en.cppreference.com/w/cpp/container/vector/resize.

    but i want to give it a try.

    Unless it's for learning purposes I suggest you avoid this low level C style. As you see for yourself it's easy to make mistakes and hard to find them later. C++ gives you a lot safer abstractions like std::vector and std::array

    For the sake of example here's how you'd do it:

    // declare type alias so the syntax later is easier
    using elem = int[2];
    
    // create
    const int old_size = 10;
    elem* arr = new elem[old_size];
    
    //resize
    const int new_size = arraySize;
    elem* temp = new elem[new_size];
    std::swap(arr, temp);
    std::memcpy(arr, temp, std::min(old_size, new_size) * sizeof(elem)); // copy old values
    if (new_size > old_size) // fill the rest with zeros
    {
        std::memset(arr + old_size * sizeof(elem), 0, (new_size - old_size) * sizeof(elem));
    }
    delete[] temp;
    
    //destroy
    delete[] arr;
    

    That's basically what vector will do for you automatically. As you can see this code is complicated and hard to read, so beyond learning please don't code like this.



  • thnx,

    that's awesome, that works great.
    just education, i was rusty.

    i didn't want to use vector, because ...

    void does_exist( const vector<vector<int>>&  table, int key )
    {
      for ( auto& row : table ) {
        std::replace( row.begin(), row.end(), key, 0 );
      }
    }
    

    http://www.cplusplus.com/forum/general/251332/

    https://stackoverflow.com/questions/50203818/check-whether-an-element-exists-in-a-2d-vector

    bool element_exist(const vector< vector<int> >&  input, int key){
        // 2d vector iterator
        vector< vector<int> >::const_iterator row_it; //iterate over each row(s)
        vector<int>::const_iterator col_it; //iterate over column(s)
        for (row_it = input.begin(); row_it != input.end(); row_it++) { // iterate each row(s)
            for (col_it = row_it->begin(); row_it != row_it->end(); col_it++) {
                if(find(row_it->begin(), row_it->end(), key) != row_it->end())
                    return true;
            }
        }
    }
    
    

    it's much easier to find a "key" and update a "value" in an array.
    alternatively you could make a array of type object instead of 2d array.
    it takes a lot more code for vectors.


  • Moderators

    bool element_exist(const std::vector<std::array<int,2> >& input, int key)
    {
        auto it = std::find_if(input.begin(), input.end(), [&](auto& elem) { return elem[0] == key || elem[1] == key; });
        return it != input.end();
    }
    

Log in to reply