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.