user2570380
user2570380

Reputation:

2D Array access violation

I tried debugging the following code, and I get an "access violation" error. I do not understand why the second loop fails when accessing the second row of elements while the first loop is able to access all the elements.

I'm messing up the *, & and [], but can't figure it out.

Thanks.

#include <iostream>

void a(const int* data, unsigned int nElements, unsigned int nColumns) {

    for (unsigned int i = 0; i < nElements; ++i)
        std::cout << data[i];

    for (unsigned int i = 0; i < nElements / nColumns; ++i)
        for (unsigned int j = 0; j < nColumns; ++j)
            std::cout << (&data)[i][j];
}

int main() {
    int arr[2][5] = {
        { 0, 1, 2, 3, 4 },
        { 5, 6, 7, 8, 9 }
    };

    a(*arr, 2 * 5, 5);

    return 0;
}

Upvotes: 0

Views: 865

Answers (4)

bitmask
bitmask

Reputation: 34654

You lost all type information once you are in your a function, so you cannot expect the subscript operators to work as you don't say what size the array has. Specify the size in the parameter listing and subscripting will work:

void a(int const (&data)[2][5]) {
  for (auto const& row : data)
    for (auto i : row)
      ::std::cout << i << " ";
  ::std::cout << ::std::endl;
}

You can then even go crazy and change the prototype to:

template <size_t R, size_t C>
void a(int const (&data)[R][C]) {

So it works for all 2D arrays.

Upvotes: 0

yizzlez
yizzlez

Reputation: 8805

*arr is equal to *(arr + 0) which is equal to arr[0]. arr[0] only has 5 nElements, not 10. Call the function like this:

a(*arr, 5, 5);

Upvotes: 0

Dimitrios Bouzas
Dimitrios Bouzas

Reputation: 42929

Change the line in the double for loop to:

std::cout << data[i * nColumns + j];

Upvotes: 1

M.M
M.M

Reputation: 141648

(&data)[i] is clearly bogus. data is a variable which is not an array. It's legal to write (&data)[0] and treat a variable like an array with one element. However, if i > 0 then you attempt to access memory after where data is stored, which is not any memory you own. (Don't mix up the pointer data with the things it is pointing to).

The syntax you are looking for is:

std::cout << data[i * nColumns + j];

This * is of course multiplication, not the dereference operator. When calling this function you are "flattening" the array by treating it as if it were a 10-element 1-D array, so you need to use arithmetic to work out the required index.

Finally, in the function call, *arr should be (int *)&arr or (int *)arr. What you have actually written is arr[0], which is a 5-element array. It's an out-of-bounds access to try and read more than 5 elements from it in your function. In practice, compilers don't try to detect out-of-bounds accesses for efficiency reasons and it will appear to work.

Upvotes: 2

Related Questions