Cesar Gimenes

2006-12-19

Economize memória combinando union e struct

Arquivado em: C/C++ — Cesar @ 08:56

Muitas vezes a informação que queremos armazenar é muito menor que um int de 32 bits, por exemplo usar uma variavel int para armazenar um dado booleano. Isso é um enorme desperdício de espaço.

Entretanto podemos combinar um int com uma struct e obter um código muito elegante, que vai economizar memória e de quebra trás algumas vantagens, veja o exemplo:

union control
{
    unsigned int flag;
    struct f
    {
        unsigned int id:16;
        unsigned int isRootWindow:1;
        unsigned int widgetType:8;
        unsigned int mouseIn:1;
        unsigned int pixelSize:3;
        unsigned int reserved:2;
    } f;
} control;

Note que declaramos uma variável unsigned int chamada flag no mesmo nível que a struct f. O union vai “unir” flag e f fazendo com que as duas variáveis tenham o mesmo endereço na memória.
Mas ai vem o truque, note na declaração dos membros da struct f nos definimos o comprimento em bits de cada um colocando no final da declaração “:n” onde n é o numero em bits.

Por exemplo: “:16″ em id faz com que ela tenha 16 bits de comprimento e colocar :1 em mouseIn faz com que ela tenha apenas um bit de comprimento.

Como a struct f e a int flag tem exatamente 32 bits de tamanho as duas combinam perfeitamente.
Como usar:

Podemos acessar cada membros individualmente como nos exemplos:
… ptr->control.f.id++; …
ou
… if (ptr->control.f.mouseIn) …

Ou podemos acessar todos de uma só vez via flag:
… ptr->control.flag = 0;

Vantagens:
Otimiza o uso da memória.
É um meio mais fácil de acessar dados booleanos que se usarmos o modo antigo usando AND, XOR,etc.
Como as informações ficam mais próximas geralmente o uso de memória cache é melhora.

Desvamtagens:
Depende da plataforma, você pode ter que ajustar seu código para ele rodar corretamente em plataformas diferentes da original.

Blog no WordPress.com.