Why can not I access the integer vector in the main () function?

4

I can not access the positions of the integer vector that I loaded in the function loads. In that function I can correctly access the data with:

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

But in the function main() , below where I call the function loads, when I try to access any position of this integer vector the program simply closes. I think 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
    }
}
    
asked by anonymous 07.10.2018 / 15:52

2 answers

5

The problem is a bit subtle because it's working with vectors and pointers, but it's simple.

Imagine this scenario:

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

Calling like this:

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

See in the ideon

It turns out 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 x parameter is a copy of the value that var1 had, so changing x in the function does not change the value of var1 .

You did exactly the same thing but with 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 exactly it is the same as the example I gave but now with a int* , an integer pointer. You create a pointer, pass it to the function in the hope that the function changes it, but remember that what is passed is a copy of the pointer. So doing n = (int *) malloc(3*sizeof(int)); does not change the n that has in the 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 
}
    
07.10.2018 / 16:41
3

The code has some problems and can be written more simply, but the main one is how much memory allocation. Prefer to allocate the memory to receive the data in the function where you will use it. And then it's easier to remember to wrap with free() . If you want a more robust code you have to do a lot of checking or reading in a different way. This code is good as a basic exercise to read something that you are sure everything will work out.

There is probably a problem with how the data is in the file. Are you sure you have a way to separate the numbers? Are they valid? I tested with a very simple file with data separated by space.

#include <stdio.h>
#include <stdlib.h>

void carrega(int *n) {
    FILE *f = fopen("arquivo.txt", "r");
    for (int i = 0; i < 3; i++) fscanf(f, "%d", &n[i]);
    fclose(f);
}

int main() {
    int *n = malloc(3 * sizeof(int));
    carrega(n);
    for (int i = 0; i < 3; i++) printf("%d\n", n[i]);
    free(n);
    system("pause");
}

I placed GitHub for future reference .

    
07.10.2018 / 16:42