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

Asked

Viewed 97 times

5

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

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

But in 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 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
    }
}

2 answers

5


The problem is kind of subtle due to working with vectors and pointers, but it’s something simple.

Imagine this scenario:

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

Calling it that:

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

Look at the ideone

It turns out that in C the parameters are always passed by copying, 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, therefore alter x function does not change the value of var1.

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

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 is exactly like the example I gave but now with a int*, a whole 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. Then do 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 
}

3

The code has some problems and can be written more simply, but the main one is how to allocate memory. Prefer to allocate the memory to receive the data in the function where you will use it. And then it becomes easier to remember librar with free(). If you want more robust code you have to do a number of checking or reading in a different way. This code is good as basic exercise to read something you’re sure will all 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 put in the Github for future reference.

  • Opa Maniero. Sorry about the weird code. I cut several things to make it simpler for you to understand what was my doubt, I did not see the malloc, I did not use the free, etc ... In fact I need to perform all the allocation within the "charge" function and then play with it in main. The Isac down here reminded me that I was passing the copy of the pointer and not the pointer itself.

  • @Eduardooliveira only that is not how people usually make me C and is a code prone to errors. In general, all libraries work with this idea of allocating and passing the pointer, its departure from the standard. It’s your right to do so, but you’re doing it in a way that’s considered bad.

  • I get it, I’m gonna follow your lead. This code that I am doing is a very specific exercise for learning, where I have a file that the 1st whole element informs the amount of integer numbers that the file has. For example: 3 90 100 87 <<< Informs that I have three integers (90,100,87) After discovering the quantity, I had to put these three in an array, find the lowest value and print the inverse order of these elements. Then the teacher asked to leave nothing on main, including the opening of the file. As I have to take the amount of elements I had to put the aperture in the charge function.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.