Why can't I access the array of integers in the main() function?

Question:

I can't access the positions of the integer array that I loaded in the load function. In that function I can correctly access the data with:

printf("%d\n", n[i]);

But in the main() function, below where I call the load function, when I try to access any position in this vector of integers the program simply closes. I believe I'm working wrong with pointers

#include <stdio.h>

void carrega (int *n);

int main
(int argc,char *argv[])
{
    int *n=NULL;
    carrega (n);
    printf("%d\n", n[0]); //Erro aqui, não consegue acessar.
}

void carrega (int *n)
{
    int i = 0;
    FILE *f = NULL;
    f = fopen ("arquivo.txt", "r");

    n = (int *) malloc(3*sizeof(int));

    for(i=0;i<3;i++){
    fscanf (f, "%d", &n[i]);
    printf("%d\n", n[i]);  //Tudo ok
    }
}

Answer:

The problem is kind of subtle because I'm working with vectors and pointers, but it's a simple one.

Imagine this scenario:

void altera(int x){
    x = 10;
}

calling like this:

int var1 = 50;
altera(var1);
printf("%d", var1); //50

See on ideone

It happens that in C the parameters are always passed by copy, so changing the value of a parameter in a function does not change the original variable. Looking at this example I gave, the parameter x is a copy of the value that var1 had, so changing x in the function doesn't change the value of var1 .

You did exactly the same but through a pointer, now see:

void carrega (int *n){
    ...
    n = (int *) malloc(3*sizeof(int));
    ...
}

int main(int argc,char *argv[]){
    int *n=NULL;
    carrega (n);
    printf("%d\n", n[0]);
}

See how it looks exactly like the example I gave but now with an int* , an integer pointer. You create a pointer, pass it to the function in the hope that the function will change it, but remember that what is passed is a copy of the pointer. Then do n = (int *) malloc(3*sizeof(int)); does not change the n that has in main but the copy of that n that has in the function.

Here are two solutions to solve

1) Return the value you wanted to change:

int* carrega (int *n);
//^-- agora retorno de int*

int main(int argc,char *argv[]) {
    int *n = NULL;
    n = carrega (n); //coloca o valor devolvido de novo em n
    printf("%d\n", n[0]);
}

int* carrega (int *n) {
//^--- agora retorno de int*
    int i = 0;
    FILE *f = fopen ("arquivo.txt", "r");
    n = (int *) malloc(3*sizeof(int));

    for(i=0; i<3; i++) {
        fscanf (f, "%d", &n[i]);
        printf("%d\n", n[i]);
    }
    return n; //retorna o novo array alocado
}

2) Pass the address of the variable you want to change:

void carrega (int **endereco_n);
//                 ^-- agora recebe o endereço do array

int main(int argc,char *argv[]) {
    int *n = NULL;
    carrega (&n); //passa o endereço do array através do &
    printf("%d\n", n[0]);
}

void carrega (int **endereco_n) {
//                 ^-- agora recebe o endereço do array
    int i = 0;
    FILE *f = fopen ("arquivo.txt", "r");
    int *n = (int *) malloc(3*sizeof(int));

    for(i=0; i<3; i++) {
        fscanf (f, "%d", &n[i]);
        printf("%d\n", n[i]);
    }
    *endereco_n = n; //altera o array do main através do endereço recebido 
}
Scroll to Top