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

6

How is it possible to create a dynamic array inside 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
}
    
asked by anonymous 24.04.2014 / 19:06

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 do not reach you, increase the array with realloc .

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

Yes, it is possible. And it's probably worth putting the size that was allotted together within 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);
}

So, 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...
}
    
08.03.2017 / 21:27