| Brellacosa Mainframe e os ponteiros de memoria do Cobol parte II |
COBOL Ponteiros de Memória: Os Cristais Kyber Escondidos do IBM Z
Parte 2 – BASED, ALLOCATE, CEEGTST e Estruturas Dinâmicas
Quando o Padawan Descobre que Pode Construir Estruturas que Não Existem Até Serem Invocadas
Por Bellacosa Mainframe
"Um registro em WORKING-STORAGE nasce junto com o programa. Um registro BASED espera pacientemente até que alguém lhe conceda um endereço. É quase como invocar um sabre de luz que ainda não possui cristal."
Mestre Sysprog Bellacosa
Introdução
Na Parte 1 aprendemos sobre:
USAGE POINTER
ADDRESS OF
SET
Stack
Heap
AMODE 24/31/64
Ponteiros inválidos
Dangling pointers
Agora vamos atravessar uma das fronteiras mais desconhecidas do COBOL moderno.
Chegou o momento do Padawan descobrir algo surpreendente.
No COBOL, podemos criar estruturas que não ocupam memória alguma até receberem um endereço válido.
Sim.
Existe praticamente uma espécie de objeto fantasma.
Uma descrição.
Uma planta arquitetônica.
Um molde.
Sem existência física.
Até alguém dizer:
SET ADDRESS OF ALGUMA-COISA
ou
ALLOCATE
E então...
A estrutura ganha vida.
O que é BASED?
BASED é provavelmente uma das palavras menos utilizadas no COBOL corporativo.
Exemplo:
01 WS-CLIENTE BASED.
O compilador entende:
"Existe uma estrutura chamada WS-CLIENTE."
Mas também entende:
"Não reserve memória para ela."
Diferença entre WS tradicional
Working Storage
01 WS-CLIENTE.
05 WS-NOME PIC X(30).
05 WS-IDADE PIC 999.
Ao carregar o programa.
Memória:
1000 WS-NOME
1030 WS-IDADE
Sempre existe.
BASED
01 WS-CLIENTE BASED.
05 WS-NOME PIC X(30).
05 WS-IDADE PIC 999.
Memória:
Nada.
Zero.
Inexistente.
Como BASED funciona?
Pense em um apartamento na planta.
Temos:
Sala
Cozinha
Banheiro
Quarto
Tudo desenhado.
Mas ainda não foi construído.
BASED é exatamente isso.
O papel do ponteiro
Precisamos de alguém para dizer:
Mestre...
O apartamento agora fica naquele endereço.
Exemplo
01 PTR-CLIENTE.
USAGE POINTER.
Associando
SET ADDRESS OF WS-CLIENTE
TO PTR-CLIENTE
Pronto.
WS-CLIENTE agora existe.
Primeiro exemplo completo
Passo 1
Definir ponteiro
01 PTR-CLI POINTER.
Passo 2
Criar estrutura BASED
01 REG-CLIENTE BASED.
05 CLI-ID.
PIC 9(5).
05 CLI-NOME.
PIC X(30).
05 CLI-SALDO.
PIC S9(7)V99.
Passo 3
Criar memória real
01 WS-AREA.
PIC X(40).
Passo 4
Associar
SET PTR-CLI
TO ADDRESS OF WS-AREA
Passo 5
Ativar
SET ADDRESS OF REG-CLIENTE
TO PTR-CLI
Passo 6
Usar
MOVE 1000
TO CLI-ID
MOVE 'BELLACOSA'
TO CLI-NOME
Resultado.
Funciona.
Mesmo sendo BASED.
O que aconteceu?
Antes
REG-CLIENTE
inexistente
Depois
PTR-CLI
↓
70001000
REG-CLIENTE
usa memória 70001000
ALLOCATE
Agora começa a magia.
Não queremos usar WS.
Queremos memória nova.
Dinâmica.
Exemplo
ALLOCATE REG-CLIENTE
Compilador solicita memória.
Heap.
Visualmente
Antes
HEAP
vazio
Depois
HEAP
7000000
REG-CLIENTE
FREE
Toda magia tem preço.
Precisamos liberar.
Exemplo
FREE REG-CLIENTE
Se esquecer.
Memory leak.
CEEGTST
Muito utilizado.
LE Runtime.
Significa.
Get Storage.
Exemplo conceitual
CALL 'CEEGTST'
LE devolve.
Endereço.
Ponteiro recebe.
Mais sofisticado.
Mais profissional.
CEEFRET
Libera memória.
Equivalente.
malloc()
free()
No mundo C.
Comparação
| COBOL | C |
|---|---|
| ALLOCATE | malloc |
| FREE | free |
| CEEGTST | malloc avançado |
| CEEFRET | free |
Criando lista encadeada
Agora o lado Jedi aparece.
Estrutura
01 NODE BASED.
05 DADO.
PIC 9(5).
05 NEXT POINTER.
Visualmente
NODE
DADO
NEXT
Primeiro nó
100
PTR=2000
Segundo
200
PTR=3000
Terceiro
300
NULL
Ligando nós
SET NEXT
TO PTR-NODE2
Pronto.
Lista encadeada.
Navegando
Começamos.
HEAD
Enquanto
PTR <> NULL
Exibe.
Avança.
Exemplo
DISPLAY DADO
SET PTR
TO NEXT
Filas
Também possível.
FIFO.
Cliente 1
↓
Cliente 2
↓
Cliente 3
Pilhas
LIFO.
Push
Pop
Peek
Tudo em COBOL.
Árvores
Mais interessante.
50
20 80
10 30
Estrutura
LEFT POINTER
RIGHT POINTER
Muito elegante.
Tabelas dinâmicas
Outra vantagem.
OCCURS tradicional.
1000 TIMES
Sempre ocupa.
Dinâmica.
Somente o necessário.
XML
Parser.
Nós.
Filhos.
Pai.
Ponteiros ajudam muito.
JSON
Excelente caso.
Objeto.
Array.
Subobjeto.
Estrutura árvore.
Performance
Muito boa.
Sem copiar dados.
Apenas endereço.
Mover.
8 bytes.
Mover.
1 MB.
Muito pior.
Heap
Mais lenta.
Que Working Storage.
Mas muito flexível.
Cuidados
Nunca esquecer FREE
Não usar memória liberada
Inicializar ponteiros
SET PTR TO NULL
Verificar retorno
Documentar
Curiosidade
Pouquíssimos desenvolvedores COBOL já implementaram uma lista encadeada real em produção.
Mas praticamente todos os produtos IBM utilizam estruturas semelhantes internamente.
CICS.
MQ.
DB2.
LE.
z/OS.
Todos.
O Conselho do Mestre Bellacosa
BASED é provavelmente a funcionalidade que mais aproxima COBOL do universo das linguagens de sistemas.
Ela permite abandonar parcialmente o modelo tradicional de registros fixos e entrar em um mundo onde estruturas podem nascer, crescer, conectar-se umas às outras e desaparecer dinamicamente.
Mas o jovem Padawan deve compreender uma verdade fundamental.
Quando utilizamos BASED, ALLOCATE, CEEGTST e ponteiros encadeados, deixamos o confortável universo dos datasets catalogados, dos OCCURS previsíveis e dos registros estáticos.
Passamos a caminhar pelos corredores escuros do Heap do Language Environment.
E nesses corredores existem criaturas perigosas chamadas:
Memory Leak
Dangling Pointer
Heap Corruption
S0C4
Storage Overlay
Abend U4038
O verdadeiro Mestre COBOL não teme essas criaturas.
Ele simplesmente sabe exatamente onde elas vivem.
Sem comentários:
Enviar um comentário