Utilizando o Tipo de Dados GArray da Biblioteca GLib

Estrutura e Conceito do GArray

O tipo GArray presente na biblioteca GLib oferece funcionalidade semelhante ao container vector da biblioteca padrão C++. Para utilizar essa estrutura, é necessário declarar um ponteiro para GArray. A definição interna da estrutura é a seguinte:

struct GArray
{
  gchar *data;
  guint len;
};

Ao inserir elementos no início ou no final do vetor, a estrutura realiza alocação dinâmica de memória automaticamente quando necessário, expandindo seu tamanho conforme a demanda.

Exemplo Prático de Uso

O código a seguir demonstra as principais operações disponíveis no GArray:

/*
 * arquivo: exemplo_garray.c
 * descricao: Demonstracao das operacoes com GArray da GLib
 * compilacao: gcc -o exemplo_garray exemplo_garray.c `pkg-config --cflags --libs glib-2.0`
 */

#include <glib.h>
#include <stdio.h>

void exibir_vetor(GArray *vetor, guint quantidade, const char *titulo)
{
    guint pos;
    printf("%s:\n", titulo);
    for (pos = 0; pos < quantidade; pos++) {
        printf("%d ", g_array_index(vetor, int, pos));
    }
    printf("\n");
}

int main(void)
{
    GArray *vetor = g_array_new(FALSE, TRUE, sizeof(int));
    guint total_elementos = 0;

    /* Insercao de elementos no final */
    int valores_iniciais[] = {100, 200, 300, 400, 500};
    guint qtd_iniciais = sizeof(valores_iniciais) / sizeof(int);
    g_array_append_vals(vetor, valores_iniciais, qtd_iniciais);
    total_elementos += qtd_iniciais;
    exibir_vetor(vetor, total_elementos, "Apos adicionar 100, 200, 300, 400, 500");

    /* Insercao individual no final */
    int valor_extra = 600;
    g_array_append_val(vetor, valor_extra);
    total_elementos++;
    exibir_vetor(vetor, total_elementos, "Apos adicionar 600 no final");

    /* Insercao no inicio */
    int novos_frent[] = {10, 20, 30};
    guint qtd_frent = sizeof(novos_frent) / sizeof(int);
    g_array_prepend_vals(vetor, novos_frent, qtd_frent);
    total_elementos += qtd_frent;
    exibir_vetor(vetor, total_elementos, "Apos inserir 10, 20, 30 no inicio");

    /* Insercao em posicao especifica */
    int valor_posicao = 999;
    g_array_insert_val(vetor, 4, valor_posicao);
    total_elementos++;
    exibir_vetor(vetor, total_elementos, "Apos inserir 999 na posicao 4");

    /* Remocao por indice com deslocamento */
    g_array_remove_index(vetor, 4);
    total_elementos--;
    exibir_vetor(vetor, total_elementos, "Apos remover elemento da posicao 4");

    /* Remocao rapida (troca com ultimo elemento) */
    g_array_remove_index_fast(vetor, 0);
    total_elementos--;
    exibir_vetor(vetor, total_elementos, "Apos remocao rapida na posicao 0");

    /* Liberacao da memoria */
    g_array_free(vetor, TRUE);

    return 0;
}

Compilacao e Execucao

Para compilra o programa, utilize o seguinte comando:

gcc -o exemplo_garray exemplo_garray.c `pkg-config --cflags --libs glib-2.0`

Ao executar o binário gerado, a saída esperada será:

Apos adicionar 100, 200, 300, 400, 500:
100 200 300 400 500 
Apos adicionar 600 no final:
100 200 300 400 500 600 
Apos inserir 10, 20, 30 no inicio:
10 20 30 100 200 300 400 500 600 
Apos inserir 999 na posicao 4:
10 20 30 100 999 200 300 400 500 600 
Apos remover elemento da posicao 4:
10 20 30 100 200 300 400 500 600 
Apos remocao rapida na posicao 0:
600 20 30 100 200 300 400 500

Detalhamento das Funcoes

g_array_new()

Responsável pela criação do vetor. Aceita três parâmetros: o primeiro indica se um caractere nulo '\0' deve ser adicionado ao final dos dados; o segundo determina se a memória alocada para os elementos deve ser zerada inicialmente; o terceiro especifica o tamanho em bytes de cada elemento armazenado.

g_array_append_val() e g_array_append_vals()

A função g_array_append_val() insere um único elemento no final do vetor, funcionando de modo análogo ao push_back() do C++. Como trata-se de uma macro que utiliza referência, não é possível passar literais diretamente — é obrigatório armazenar o valor em uma variável previamente.

A variante g_array_append_vals() permite inserir múltiplos eelmentos de uma só vez no final da estrutura.

g_array_prepend_val() e g_array_prepend_vals()

Essas funções realizam a inserção de elementos no início do vetor, sendo que a versão com "s" aceita um array de valores para inserção em lote.

g_array_insert_val()

Permite inserir um elemento em uma posição arbitrária do vetor. Todos os elementos a partir dessa posição são deslocados uma posição para frente.

g_array_index()

Macro para acesso direto a elementos por índice. Requer três argumentos: o vetor alvo, o tipo de dado dos elementos e o índice desejado.

g_array_remove_index()

Remove o elemento na posição especificada. Os elementos subsequentes são deslocados para preencher a lacuna, mantendo a ordem original.

g_array_remove_index_fast()

Executa a remocao de um elemento de forma otimizada, substituindo o elemento alvo pelo último elemento do vetor e depois eliminando a posição final. Essa abordagem é mais eficiente, porém altera a ordem dos elementos.

g_array_free()

Desaloca toda a memória associada ao vetor. O segundo parâmetro, quando defniido como TRUE, também libera o buffer interno de dados.

Mais informações na documentação oficial da GLib.

Tags: glib GArray C estrutura-de-dados vetor-dinamico

Publicado em 7-6 03:44