It’s no nonsense.
In function libraries, it is very common to have routines that take care of memory space allocation and misallocation, primarily for more complex structures.
What is wrong here is your understanding of pointer passing by function argument. I will explain.
In function main()
, you declared a pointer vet
for an integer, but this pointer has not yet been initialized:
int *vet, tam, *p;
Already the function alocavet()
expects to receive the address of a memory space by means of a pointer, also named vet
:
void alocavet(int tam, int *vet)
So you call alocavet()
in main()
and passes to the vet
of alocavet()
an invalid address, content that was there in the memory space of the uninitialized variable.
But that doesn’t matter much. Right 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 something, not yet initialized. And then, in the first loop, you use this invalid address in scanf
, what makes the program break.
What happened to the allocation made by alocavet()
?
It’s still there, but it lost the only reference it had. The pointer vet
of alocavet()
was destroyed when the function returned.
I know. You hoped that alocavet()
would change the content pointed by vet
of main()
.
One way to solve this is by using pointer:
void alocavet(int tam, int **vet){
*vet = (int*) malloc (tam * sizeof(int));
}
In this way, vet
of main()
would continue to be stated in the same way, as a pointer to an integer:
int *vet;
And you would pass the address of this pointer vet
using the operator &
:
alocavet(tam, &vet);
This is enough to initialize the pointer on main()
and, in addition, obtain the return of malloc()
, to check if the allocation is unsuccessful, as said here, and also release memory after used.
Look how it turned out:
#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);
}
Did any of the answers solve your question? Do you think you can accept one of them? Check out the [tour] how to do this, if you haven’t already. You would help the community by identifying what was the best solution for you. You can accept only one of them. But you can vote on any question or answer you find useful on the entire site.
– Maniero