It's no nonsense.
In function libraries, it is very common to have routines that handle allocation and deallocation of memory space, especially for more complex structures.
What is wrong here is your understanding of pointer passing by function argument. I'll explain.
In main()
, you declared a vet
pointer to an integer, but this pointer has not yet been initialized:
int *vet, tam, *p;
The alocavet()
function expects to receive the address of a memory space by means of a pointer, also named vet
:
void alocavet(int tam, int *vet)
Then you call alocavet()
in main()
and pass vet
alocavet()
an invalid address, content that was there in memory space of uninitialized variable.
But that does not matter much. In the first line of alocavet()
, the invalid address received by vet
is replaced by the address of the new memory space returned by malloc()
.
void alocavet(int tam, int *vet){
vet = (int*) malloc (tam * sizeof(int));
}
When alocavet()
returns, the pointer vet
in main()
keeps pointing to nothing since it has not yet been initialized. And then, in the first loop, you use this invalid address in scanf
, which causes the program to crash.
What happened to the allocation made by alocavet()
?
It's still there, but you lost the only reference you had. The pointer vet
of alocavet()
was destroyed when the function returned.
I know. You expected% w /% to change the content pointed to by alocavet()
of vet
.
One way to resolve this is by using pointer pointers:
void alocavet(int tam, int **vet){
*vet = (int*) malloc (tam * sizeof(int));
}
In this way, main()
of vet
would still be declared the same as a pointer to an integer:
int *vet;
And you would pass the address of this main()
pointer using the vet
:
alocavet(tam, &vet);
This is sufficient to initialize the pointer in &
and, in addition, get the return of main()
, to check if the allocation is unsuccessful, as they said here, and also release memory after it is used. >
See how it went:
#include <stdio.h>
#include <stdlib.h>
void alocavet(int tam, int **vet) {
*vet = (int *) malloc ( tam * sizeof(int));
}
void desalocavet(int **vet) {
if (*vet) {
free(*vet);
*vet = 0;
}
}
int main(){
int *vet, tam, *p;
printf("Tamanho do vetor: ");
scanf("%d", &tam);
alocavet(tam, &vet);
if (vet == NULL) abort();
p = vet;
printf("Entre com os elementos do vetor: ");
for (int c=0; c<tam; c++) scanf("%d", &*p++);
p = vet;
printf("Elementos do vetor: ");
for (int c=0; c<tam; c++) printf("%d ", *p++);
desalocavet(&vet);
}