Dynamic allocation with a void function

0

I made a simple code using dynamic allocation. Just ask for the size of the vector, to insert data and print it at the end

I can do dynamic allocation with int , returning vet , but as I'm learning, I'm trying to do a few different things ...

I do not know if it's too absurd to try this. But can you explain why that does not work?

void alocavet(int tam, int *vet){
    vet = (int*) malloc (tam * sizeof(int));
}

int main(){
    int *vet, tam, *p;

    printf("Tamanho do vetor: ");
    scanf("%d", &tam);

    alocavet(tam, vet);

    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++);
}
    
asked by anonymous 28.07.2018 / 23:40

3 answers

0

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);
}
    
05.08.2018 / 07:06
4

There is no need to encapsulate the malloc function, even more in this way, you could even get the return of it, however, you would have to evaluate the gain and consider the context, but how and learning can only use malloc .

Below is the code to allocate the memory block for vetor , see:

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

int main(void) 
{
  int i;
  size_t tam;
  int *vetor;
  printf("Tamanho:");
  scanf("%zu", &tam);
  vetor = malloc(tam * sizeof * vetor);
  if (vetor == NULL) 
    exit(EXIT_FAILURE);
  for (i = 0; i < tam; i++) 
    vetor[i] = i + 1;
  for (i = 0; i < tam; i++) 
    printf("%i\n", vetor[i]);
  free(vetor);
  return EXIT_SUCCESS;
}

Always remember to check the return of the malloc function, being NULL in case of a failure in the allocation, and in case of success the address that points to the allocated block by function. And when you finish using the variable allocated by the function use the free() function to deallocate the memory block that was previously allocated.

See working at repl.it .

You have a question from me at subject matter .

Learn more about malloc and the function free .

    
29.07.2018 / 00:42
4

Yes, it is absurd to do this. Even to learn does not seem appropriate because you are learning to do something wrong that should not be done. It's even easier to do it the right way. And the fact that he did it the wrong way gave him room to be even more wrong since he did not release his memory. Ok that this is just an exercise and will not cause any harm, the code ends soon and memory is released by OS, but it gives the impression that it never needs and learn to do wrong. The same goes for checking if the allocation was successful, which is needed in real code, but in workout it is ok.

Having a function with no result return ( void ) has nothing to do with it. It is rarely interesting to allocate memory within a function if it will need the data where it calls the allocator function. Always allocate where you will use the data. You can pass an allocation forward, but not backward.

You can do this as an abstraction, but you need to understand what you are doing, which is not the case.

This case probably would not even require a dynamic allocation. You even need it because it asks for a int , but it's unlikely to allocate more than it fits in short , or even char . And this fits into stack , so allocation in heap would be unnecessary. Okay, I understand it's just for exercise, but it's good to make it clear so you do not learn wrong.

This is not the first time I see your code changing the vector address instead of using an index. That is, it is not evolving, review the way you are learning.

If you want to learn different things look for different real problems. Learning error is learning, but learning wrong is not.

In this case you do not have to do more than this:

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

int main() {
    int tam;
    printf("Tamanho do vetor: ");
    scanf("%d", &tam);
    int *vet = malloc(tam * sizeof(int));
    printf("\nEntre com os elementos do vetor:\n");
    for (int i = 0; i < tam; i++) scanf("%d", &vet[i]);
    printf("Elementos do vetor:\n");
    for (int i = 0; i < tam; i++) printf("%d ", vet[i]);
}

See running on ideone . And no Coding Ground . Also I put it in GitHub for future reference .

    
28.07.2018 / 23:54