How to use realloc() dynamically in struct allocation?

Asked

Viewed 1,901 times

5

I have a structure struct TMedidorEletrico *medidor;, and it is necessary to reallocate the memory to this structure dynamically, until the user closes the loop. Memory must be reallocated one step at a time, but when it invokes the function realloc() for the second time causes the following error:

* Error in `./Ex14companiaeletrica': realloc(): invalid next size: 0x000001c46010 * Aborted (recorded core image)*

Code:

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

int criaEstrutura(void);

struct TMedidorEletrico
{
    int numero_consumidor; //Numero do consumidor.
    float kWh_mensal; //Quantidade de kWh consumido ao mes.

    int tipo;
    /* 1 – residencial, preço em reais por kWh = 0,3
       2 – comercial, preço em reais por kWh = 0,5
       3 – industrial, preço em reais por kWh = 0,7
    */
    float custo_total;
};

struct TMedidorEletrico *medidor;

int main(void)
{
    criaEstrutura();

    float total_consumo_geral = 0.0,
          qtd_tipo1,
          qtd_tipo2;
    int qtdLeitura = 0;

    while(1)
    {
        printf("\nInforme o numero do %d consumidor: ", qtdLeitura + 1);
        scanf("%d", &medidor[qtdLeitura].numero_consumidor); //Se o usuario digitar 0 encerra o loop while.
        __fpurge(stdin);

        printf("\nInforme o consumo do kWh total no mes: ");
        scanf("%f", &medidor[qtdLeitura].kWh_mensal);
        __fpurge(stdin);

        printf("\nInforme o tipo, 1-Residencial 2-Comercial 3-industrial: ");
        scanf("%d", &medidor[qtdLeitura].tipo);
        __fpurge(stdin);

        if(medidor[qtdLeitura].numero_consumidor == 0) //Condição que encerra o loop.
            break;
        else
            if(medidor != NULL) //Testa caso == a NUULL siguinifica que na a mais espaco na memoria para realocar.
            {
                qtdLeitura++;

                /*Quando passa aqui pela primeira vez ocorre tudo certo, porem na segunda vez da erro.*/
                medidor = (struct TMedidorEletrico *) realloc(medidor, sizeof(struct TMedidorEletrico) * 1);
            }
            else
                break;
    }

    return 0;
}


int criaEstrutura(void)
{
    medidor = (struct TMedidorEletrico *) (malloc(sizeof(struct TMedidorEletrico) * 1)); //Aloca a primeira vez

    return 0;
}

I would like the program to continue storing the values in the structure for future treatment.
Thank you for your attention.

1 answer

2


The program is relocating but maintaining the same size:

sizeof(struct TMedidorEletrico) * 1

realloc() does not "sum" the size that is passed as the second parameter. This will be the new total size. To achieve the expected result, which is to make room for more elements, realloc should use the size

sizeof(struct TMedidorEletrico) * (qtdLeitura + 1)
  • Thanks for the help, I will implement here, and I will return to post the result.

  • I made the change, but the error persists.

  • 1

    There was still an off-by-one error in my reply, I already edited above. Just as in the first malloc(), realloc() has to add 1 in qtyLeitura. I tested the code even with Valgrind and it worked. By the way, there is the tip to use Valgrind in a next problem of these (I do not know if you are developing on Linux.)

  • I was the test here and it worked. Thanks a lot for the help... Another question, I never heard about Valgrind what it would be? I am developing on linux (Ubuntu 14.04), the IDE and codeblocks with GCC.

  • Valgrid is a debugging program that tests every access to memory, so if there is an attempt to access outside the size of an area, as was the case with you, it warns you at the time it happened, well before the program breaks.

  • Thanks, I’ll install it here and start using.

  • Could you tell me which commands to specify for Valgrind?

  • 1

    None, just call Valgrind . /binary

Show 3 more comments

Browser other questions tagged

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