Is it possible to implement a dynamic array within a C structure?

Asked

Viewed 1,552 times

6

How is it possible to create a dynamic array within a structure

Example

typedef struct historico_de_fabrica {
    Hist_id_rolos rolos[1000]; //<- este array em vez de ter 1000 posições queria em
                               //memoria dinâmica para ter um tamanho ajustável ao incremento
}

2 answers

6

Yes. Uses pointers and malloc()/realloc() and free()

#include <stdlib.h> // malloc(), realloc(), free()

struct historico_de_fabrica {
    Hist_id_rolos *rolos;
};

struct historico_de_fabrica obj;
obj.rolos = malloc(1000 * sizeof *obj.rolos);
if (obj.rolos == NULL) /* erro */;
// ...
free(obj.rolos);

If, in the middle of the execution, you notice that 1000 positions are not enough for you, increase the array with realloc.

if (needmore) {
    Hist_id_rolos *temp;
    temp = realloc(2000 * sizeof *temp);
    if (!temp) /* erro */;
    obj.rolos = temp;
}
  • 2

    Could create functions like criar_historico(historico_de_fabrica* foo, int size) to facilitate creation, editing, resizing memory, this makes code more reusable.

  • 3

    Another point is that when the size is no longer known, it is useful to store the size of the array in a member variable.

  • 1

    Just as an add-on, note that in this case, your struct will no longer have an array, but a pointer to any memory position. In practice, be careful if you do "obj2 = obj". In this case, "obj2.rollers" and "obj.rollers" will point to the same place. That is, if you change the value of "obj.rollers", the value of "obj2.rollers" will also be changed.

2

Yes, it’s possible. And it’s probably interesting to put the size that was allocated together within the struct, for future use:

typedef struct historico_de_fabrica {
    Hist_id_rolos *rolos;
    size_t tamanho;
} historico_de_fabrica;

// As funções abaixo são sugestões de como implementar uma interface
// para a sua estrutura. Organizar dessa maneira, e só usar as funções
// de interface para acessar a struct, geralmente torna a manutenção
// do código muito mais fácil. Mas cada caso tem que ser avaliado
// se compensa ou não definir as funções de interface.

void alocar_historico_de_fabrica(historico_de_fabrica *hist, size_t tamanho)
{
    hist->rolos = malloc(tamanho * sizeof *hist->rolos);
    hist->tamanho = tamanho;
}

void desalocar_historico_de_fabrica(historico_de_fabrica *hist)
{
    free(hist->rolos);

    // zera o conteúdo de hist, de modo que o ponteiro será NULL,
    // e o tamanho será 0.
    memset(hist, 0, sizeof *hist);
}

Then, at some point in the code you need to use the dynamic array, you will have the size together:

for(size_t i = 0; i < hist->tamanho; ++i) {
    Hist_id_rolos *elem = &hist->rolos[i];
    // faça alguma coisa com elem...
}

Browser other questions tagged

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