1

I am trying to understand the values/pointers management in arrays.

Imagine an array of 5 elements and altering them from a function outside main. I have to use pointers. I have made this simple program to try to execute it:

#include <stdio.h>

void Mudar (int **cartao2)
{
    *cartao2[0] = 5;
    *cartao2[1] = 4;
    *cartao2[2] = 3;
    *cartao2[3] = 2;
    *cartao2[4] = 1;
}

int main()
{
    int cartao[] = {1,2,3,4,5};

    printf("int cartao[] = {");
    for (int i = 0; i < 4; i++)
        printf("%d,", cartao[i]);
    printf("%d};\n",cartao[4]);

    Mudar(&cartao);

    printf("int cartao[] = {");
    for (int i = 0; i < 4; i++)
        printf("%d,", cartao[i]);
    printf("%d};\n",cartao[4]);

}

This program gives error while executing but only when trying to execute line 5. It even prints

int cartao[] = {1,2,3,4,5};

What is wrong here.

The next step is trying to change a value inside an array of arrays. Any tips to achieve that?

EDIT

As @Stephen Docy point this code now works

#include <stdio.h>

void Mudar (int *cartao2)
{
    cartao2[0] = 5;
    cartao2[1] = 4;
    cartao2[2] = 3;
    cartao2[3] = 2;
    cartao2[4] = 1;
}

int main()
{
    int cartao[] = {1,2,3,4,5};

    printf("int cartao[] = {");
    for (int i = 0; i < 4; i++)
        printf("%d,", cartao[i]);
    printf("%d};\n",cartao[4]);

    Mudar(cartao);

    printf("int cartao[] = {");
    for (int i = 0; i < 4; i++)
        printf("%d,", cartao[i]);
    printf("%d};\n",cartao[4]);

}

And the output is

int cartao[] = {1,2,3,4,5}; int cartao[] = {5,4,3,2,1};

But now I'm curious should't this work the same way?

#include <stdio.h>

void Mudar (int *cartao2)
{
    int aux = 25;
    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            cartao2[i][j] = aux;
            aux--;
        }
    }
}

int main()
{
    int cartao[5][5];
    int aux = 1;

    //populates cartao from 1 to 25
    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            cartao[i][j] = aux;
            aux++;
        }
    }

    //prints before changing
    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            printf("%2d ", cartao[i][j]);
        }
        printf("\n");
    }

    Mudar(cartao);

    //prints after changing
    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            printf("%2d ", cartao[i][j]);
        }
        printf("\n");
    }

}

Because the program doesn't even compile:

testes7.c:10: error: pointer expected

But it is used the same way as the code that now works well.

12
  • Which line is line 5? Commented Feb 21, 2018 at 23:34
  • *cartao2[0] = 5; @KenY-N Commented Feb 21, 2018 at 23:40
  • what are your compiler warnings telling you?? Commented Feb 21, 2018 at 23:48
  • @MFisherKDX nothing. The program compiles. When executed through cmd it gives error, without explaining nothing more. Just the program testes7.c has stopped working (in my case it is said in portuguese). But now, with the multi-dimensional array it does not compile... Commented Feb 22, 2018 at 0:02
  • 1
    if you have other questions ask a new one, nobody will read through question1 to find that is answered and that there is a question2 buried at the end Commented Feb 22, 2018 at 0:12

3 Answers 3

3

Stephen Docy gave you a solution as to how to pass an array to a function. I'd like to comment on the way you did and why it fails.

int cartao[] = {1,2,3,4,5};

This creates an int[5] array. &array has the type int (*)[5], which is a pointer to an int[5] array.

Your function a double pointer int **cartao2. This type is not the same as int (*)[5], your compiler should have warned you about this with

a.c:21:11: warning: passing argument 1 of ‘Mudar’ from incompatible pointer type [-Wincompatible-pointer-types]
     Mudar(&cartao);
           ^
a.c:3:6: note: expected ‘int **’ but argument is of type ‘int (*)[5]’
 void Mudar (int **cartao2)
      ^~~~~

Mudar sees a double pointer and when you do

*cartao2[2] = 3;

you are doing cartao2[2][0] = 3, but because you didn't pass the correct type, you are dereferencing at the incorrect position in memory and writing where you shouldn't. You would have to write your function like this:

void Mudar (int (*cartao2)[5])
{
    cartao2[0][0] = 5; // or (*cartao2)[0] = 5;
    cartao2[0][1] = 4; // or (*cartao2)[1] = 4;
    cartao2[0][2] = 3; // or (*cartao2)[2] = 3;
    cartao2[0][3] = 2; // or (*cartao2)[3] = 2;
    cartao2[0][4] = 1; // or (*cartao2)[4] = 1;
}

In this case the function expects a pointer to int[5]. Note that if you declare it to accept a pointer to an array of any size, you would have to declare it as

void Mudar(int (*cartao2)[], size_t len)
{
    for(size_t i = 0; i < len; ++i)
        (*cartao2)[i] = 10*i;
}

In this case you cannot use the notation cartao2[0][i], because the compiler doesn't know the real size of the array, however (*cartao2)[i] works.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much @Pablo for this answer! What program do you use to get that errors pointed? Would you be able to help with the multidimensional arrays?
+1, You beat me by a couple minutes. I'll delete my answer shortly as there is no additional information there.
I use valgrind to detect leaks and improper access to arrays and memory and gdb to debug when I want to step through the code.
2

Unlike simple, scalar variables like int, arrays get passed as pointers, so you don't need to pass in the address of cartao in order to update its contents. Now if you wanted to change what memory block cartao was pointing to, then you would need to pass in its address.

void Mudar(int *cartao2)
{
    cartao2[0] = 5;
    cartao2[1] = 4;
    cartao2[2] = 3;
    cartao2[3] = 2;
    cartao2[4] = 1;
}

Mudar(cartao);

output :

int cartao[] = {1,2,3,4,5};
int cartao[] = {5,4,3,2,1};

4 Comments

It worked @Stephen Docy... What if cartao was cartao[5,5], how would I be able to change cartao[3,3] value?
Ok, but it would be helpful if you explained why the OP's method does not work. It's not necessarily obvious.
No, it's not @MFisherKDX. Pointers has not been easy to learn for me.
@HélderLima -- ok. I'll try to post an answer shortly explaining.
0

For 2D array ,try this . M is rows ,n is columns. In mudar function .

 for (i = 0; i < m; i++)
  for (j = 0; j < n; j++)
    *((arr+i*n) + j) =aux;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.