2

I am learning C and I am confused why the matrix in main changes in the function change. I am assuming that the matrix was passed in the function change as ma[10][10] and that matrix m shouldn't change because I declared it in main, right? Can someone explain what is happening in this case? How do I fix it?

thx for help

void change(int ma[2][3]){
    int l, c;
    for(l=0; l<2; l++){
        for(c=0; c<3; c++){
            ma[l][c]=1;
        }
    }
}
int main()
{
    int m[2][3], l, c;
    for(l=0; l<2; l++){
        for(c=0; c<3; c++){
            m[l][c]=0;
        }
    }
    change(m);
    for(l=0; l<2; l++){
        for(c=0; c<3; c++){
            printf("%d", m[l][c]);
        }
        printf("\n");
    }
    return 0;
}

I was expecting to see this:

000
000

What i get:

111
111
  • 3
    Functions can't really have array parameters. If you try to make one, it's automatically replaced with a pointer; your function is equivalent to `void change(int (*ma)[3])`. – HolyBlackCat Jun 11 '20 at 08:09
  • 2
    I guess the real question is why you expect a function named `change` _not_ to change the passed array. How does that make sense? What do you want to "fix", do you want a function that doesn't change an array? What good would that do? – Lundin Jun 11 '20 at 08:47
  • 1
    dupe of [Passing an array as an argument to a function in C](https://stackoverflow.com/questions/6567742/passing-an-array-as-an-argument-to-a-function-in-c) – underscore_d Jun 11 '20 at 09:01
  • 1
    Related: [Why it is not allowed to pass arrays by value to a function in C and C++?](https://stackoverflow.com/questions/671074/why-c-or-c-does-not-allow-passing-array-by-values-to-function) – RobertS supports Monica Cellio Jun 11 '20 at 09:05

2 Answers2

3
void change(int ma[2][3]){ ...
......
int m[2][3];
change(m);

"Why does the matrix in main change?"

You pass the array m by reference to the function change.

The parameter int ma[2][3] is in fact not an array, it is a pointer of type int (*)[3] and will point to the address of the first element of m in main().

That is why m in main got changed.

"How do I fix it?"

C does not allow to pass or return arrays by value to or from functions.

However, there are workarounds. You can f.e. wrap the array into a structure and then access the array inside of the structure. The structure you can pass and return by value.

#include <stdio.h>

#define ROWS 2
#define COLS 3

struct x {
    int m[ROWS][COLS];
};

static void no_change (struct x b) 
{
    int l, c;
    for ( l = 0; l < ROWS; l++) {
        for ( c = 0; c < COLS; c++ ) {
            b.m[l][c] = 1;
        }
    }
}

int main (void)
{
    int l, c;
    struct x a;

    for ( l = 0; l < ROWS; l++ ) {
        for ( c = 0; c < COLS; c++ ) {
            a.m[l][c] = 0;
        }
    }

    no_change(a);

    for ( l = 0; l < ROWS; l++ ) {
        for ( c = 0; c < COLS; c++ ) {
            printf("%d", a.m[l][c]);
        }
        printf("\n");
    }
    return 0;
}

Output:

000
000
0

Because the arrays are passed by the pointer not the value.

So you work on the same array.

In C only scalar types, structs and unions are passed by value

How can I fix it?

You can't fix it. If you really want to pass the array by value, you need to wrap it into the struct

typedef struct
{
    int arr[2][3]
}ARR_WRAP;

void change(ARR_WRAP ma)
{
    int l, c;
    for(l=0; l<2; l++)
    {
        for(c=0; c<3; c++)
        {
            ma.arr[l][c]=1;
        }
    }
}

int main()
{
    ARR_WRAP m;
    for(int l=0; l<2; l++)
    {
        for(int c=0; c<3; c++)
        {
            m.arr[l][c]=0;
        }
    }
    change(m);
    for(int l=0; l<2; l++)
    {
        for(int c=0; c<3; c++)
        {
            printf("%d", m.arr[l][c]);
        }
        printf("\n");
    }
    return 0;
}
0___________
  • 60,014
  • 4
  • 34
  • 74