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