Problem with dynamic allocation - realloc()

Asked

Viewed 202 times

3

I’m doing a program that works as a payroll system, but I’m having trouble with the dynamic allocation part. The program runs only once and stops. No int(main) i put:

    printf("Sizeof : %d\n",sizeof(funcionarios));
    printf("Executou: %d\n",i+1);
    printf("Tamanho: %d\n\n",tamanho);

To try to identify where the error was. In the second execution sizeof() returns the same value which led me to believe that the realloc() did not reallocate the memory. I may be wrong, I am still learning. I ask for help from someone more enlightened than me.

Complete code below:

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

typedef struct{
    int matricula;
    float salario;
}Funcionario;

int ler_dados(void){
    int dado;
    printf("Digite a matrícula:\t");
    scanf(" %d",&dado);
    return dado; 
}
float ler_salario(void){
      float salario;
      printf("Digite o valor do salário:\t");
      scanf(" %f",&salario);
      return salario;
}
int inserir_funcionario(Funcionario *funcionarios, int tamanho){
    int qntd = sizeof(funcionarios) * (tamanho + 1);
    funcionarios = realloc(funcionarios, qntd);
    funcionarios[tamanho].matricula = ler_dados();
    funcionarios[tamanho].salario = ler_salario();
    tamanho++;
    return tamanho;
}
int main(void){
    setlocale(LC_ALL,"Portuguese");
    int i;
    Funcionario *funcionarios = malloc(sizeof(funcionarios));
    int tamanho = 0;
    for(i=0; i<5; i++)
    {
        printf("Sizeof : %d\n",sizeof(funcionarios));
        printf("Executou: %d\n",i+1);
        printf("Tamanho: %d\n\n",tamanho);
        tamanho = inserir_funcionario(funcionarios, tamanho);
    }
}

1 answer

1


The mistake was up to mine in your previous question. I focused on the main problem and missed another mistake. But I remember that relocating in this way is still inadequate as I said before, and this new problem is the result of it. It complicates a lot. Memory management should be treated in an isolated way and preferably in the same place where the variable was created, it is much easier.

This problem occurred because it is passing the memory pointer to be treated, and this allows you to change the data that is in this memory location. But it does not allow you to change the pointer. You can even change it, but it will only be seen inside the function where it was changed. When you give the realloc() it changes the pointer inside inserir_funcionario(), but outside it the pointer has not been modified, and then the confusion begins. At the next run of the function it is getting the original pointer not relocated, and at some point it will cause corruption problem or even, luckily, break the application.

The solution is to pass to the pointer by reference, so you end up having to make a double pointer in the passage, and you have to skid it to use.

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

typedef struct {
    int matricula;
    float salario;
} Funcionario;

int ler_dados(void) {
    int dado;
    printf("Digite a matrícula:\t");
    scanf(" %d", &dado);
    return dado; 
}
float ler_salario(void) {
      float salario;
      printf("Digite o valor do salário:\t");
      scanf(" %f", &salario);
      return salario;
}
int inserir_funcionario(Funcionario **funcionarios, int tamanho) {
    *funcionarios = realloc(*funcionarios, sizeof(Funcionario) * (tamanho + 1));
    (*funcionarios)[tamanho].matricula = ler_dados();
    (*funcionarios)[tamanho].salario = ler_salario();
    return ++tamanho;
}
int main(void) {
    setlocale(LC_ALL,"Portuguese");
    Funcionario *funcionarios = malloc(sizeof(Funcionario));
    int tamanho = 0;
    for (int i = 0; i < 5; i++) {
        printf("Sizeof : %lu\n", sizeof(Funcionario));
        printf("Executou: %d\n", i + 1);
        printf("Tamanho: %d\n\n", tamanho);
        tamanho = inserir_funcionario(&funcionarios, tamanho);
    }
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

To simplify you can do so:

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

typedef struct {
    int matricula;
    float salario;
} Funcionario;

int ler_dados(void) {
    int dado;
    printf("Digite a matrícula:\t");
    scanf(" %d", &dado);
    return dado; 
}
float ler_salario(void) {
      float salario;
      printf("Digite o valor do salário:\t");
      scanf(" %f", &salario);
      return salario;
}
int inserir_funcionario(Funcionario *funcionarios, int tamanho) {
    funcionarios[tamanho].matricula = ler_dados();
    funcionarios[tamanho].salario = ler_salario();
    return ++tamanho;
}
int main(void) {
    setlocale(LC_ALL,"Portuguese");
    Funcionario *funcionarios = malloc(sizeof(Funcionario));
    int tamanho = 0;
    for (int i = 0; i < 5; i++) {
        printf("Sizeof : %lu\n", sizeof(Funcionario));
        printf("Executou: %d\n", i + 1);
        printf("Tamanho: %d\n\n", tamanho);
        funcionarios = realloc(funcionarios, sizeof(Funcionario) * (tamanho + 1));
        tamanho = inserir_funcionario(funcionarios, tamanho);
    }
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

Browser other questions tagged

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