0

I read how to pass 2-D arrays in a function as a parameter and tried to implement the same. There are two problems which I encountered:

1) The first line of the output of the code contains garbage value. 2) What does the line ((arr + in) + j) actually do ? I mean, Why can't we do something like ((arr + i) + j) to access arr[i][j] ?

I also tried passing the matrix using parameter int **arr and then tried printing the value as arr[i][j] but there was no output.

Here is the output that I get:-

Enter number of nodes: 4
0167772161878012032-1
0000
0000
0000

And here is my code :-

#include <iostream>
using namespace std;

void show(int* arr, int n)
{
    int i, j;

    for(i = 0; i < n; ++i)
    {
        for(j = 0; j < n; ++j)
        {
            cout << *((arr + i*n) + j);
        }

        cout << endl;
    }
}

int main()
{
    int n, i, j;

    cout << "Enter number of nodes: ";
    cin >> n;

    int arr[n][n] = {{0}}; //Will initialize all elements in the matrix with 0.

    show((int*)arr, n);
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Chinmay Vemuri
  • 179
  • 2
  • 9
  • Prefer text before pictures. It's hard to copy text from pictures. I edited it this time. – Ted Lyngmo Feb 15 '20 at 13:10
  • And when you used your debugger to run your program, what did you see? This is what a debugger is for. If you don't know how to use a debugger this is a good opportunity to learn how to use it to run your program one line at a time, monitor all variables and their values as they change, and analyse your program's logical execution flow. Knowing how to use a debugger is a required skill for every C++ developer, no exceptions. With your debugger's help you should be able to quickly find all bugs in this and all future programs you write, without having to ask anyone for help. – Sam Varshavchik Feb 15 '20 at 13:11
  • That's not valid C++ code because there are no variable-length arrays (VLA) in C++: `cin >> n; int arr[n][n] = {{0}};` – Thomas Sablik Feb 15 '20 at 13:13
  • your code uses a varibale length array, which is not standard c++, https://stackoverflow.com/questions/1887097/why-arent-variable-length-arrays-part-of-the-c-standard c++ has `std::vector`, use it – 463035818_is_not_an_ai Feb 15 '20 at 13:14
  • This line `cout << *((arr + i*n) + j);` causes undefined behavior. `arr` is a pointer to an array that contains `n` elements. You are not allowed to add a value larger `n` to arr and you are not allowed to read `arr + n` – Thomas Sablik Feb 15 '20 at 13:17
  • @ThomasSablik `i < n` and `i < n` should make it ok? – Ted Lyngmo Feb 15 '20 at 13:18
  • @TedLyngmo `arr + i*n` causes undefined behavior for `i` > 1. I know that many people do such things but they are not allowed by the standard. – Thomas Sablik Feb 15 '20 at 13:19
  • @ThomasSablik Ah, I missed the point. I though you meant that it was out of bounds. Do you have a ref for it being forbidden? All elements are guaranteed to be contiguous dispite the number of dimensions. – Ted Lyngmo Feb 15 '20 at 13:21
  • @TedLyngmo http://eel.is/c++draft/expr.add#4. _"All elements are guaranteed to be contiguous"_ do you have a ref for this? AFAIK this is not guaranteed especially for dynamically allocated variable-length arrays using a compiler extension. – Thomas Sablik Feb 15 '20 at 13:23
  • I just used vectors instead of arrays to do what I wanted. It is much easier to work with for the time being. Thank you @idclev463035818 for the suggestion ! – Chinmay Vemuri Feb 15 '20 at 13:33
  • 1
    you almost never have to use c-arrays. Vectors are for dynamic size and `std::array` for fixed size – 463035818_is_not_an_ai Feb 15 '20 at 13:38
  • @ThomasSablik Thanks. I _think_ you are correct about the out of bounds access part for the first dimention even though I can't see that in that part of the spec. and [dcl.array#9](http://eel.is/c++draft/dcl.array#9) doesn't make it explicitly clear by mentioning "_The **overall** array **can** be viewed as a three-dimensional array of integers_". There's probably a more general note about out of bounds indexes somewhere though. – Ted Lyngmo Feb 15 '20 at 13:38
  • [ES.49: If you must use a cast, use a named cast](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Res-casts-named) You should avoid `(int*)arr`. I don't know if it's allowed to dereference such a casted pointer. – Thomas Sablik Feb 15 '20 at 13:41
  • @ThomasSablik I'm all for readability but making unreadable code doesn't make it UB. :-) – Ted Lyngmo Feb 15 '20 at 13:51

2 Answers2

2

The biggest problem here is that you are using C and not C++.

To avoid people gasping and starting religious or political discussion, let's nail it down to:

VLAs (Variable Length Arrays) are not allowed in C++.

Additionally, you should never use raw pointers for owned memory and no pinter arithmetic.

And then the main topic:

Issue in Passing a 2-D array

The used syntax for passing arrays to function is wrong. In C++ arrays can be passed by reference or by pointer. Please see:

void function1(int(&m)[3][4])   // For passing array by reference
{}
void function2(int(*m)[3][4])   // For passing array by pointer
{}

int main()
{
    int matrix[3][4]; // Define 2 dimensional array

    function1(matrix);  // Call by reference
    function2(&matrix); // Call via pointer 
    return 0;
}

Of course we can do all kind of dirty designs with pointers. Even accepting pointer decays. But we should not do it.

A M
  • 14,694
  • 5
  • 19
  • 44
0

Variable length arrays is not a standard C++ feature.

Nevertheless you passed to the function a pointer to the first element of a two-dimensional array.

Each "row" of the two-dimensional array has n elements. So if you have a pointer to the first element of the first row then to get the pointer to the first element of the second row you have to write

arr + n

If you want to get the first pointer to the i-th row of the two-dimensional array you have to write

arr + i * n

To get pointer to an element within the row you have to write

( arr  + i * n ) + j

that is the same as

arr + i ( n + j

to get the element pointed to by the pointer you have to dereference the pointer

*( arr + i * n + j )
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/207911/discussion-on-answer-by-vlad-from-moscow-issue-in-passing-a-2-d-array). – Bhargav Rao Feb 16 '20 at 00:27