Bsico de ponteiros com o GDB
[Warning: This post is a backup recovery from my previous Wordpress blog. All content was automatically converted accessing a MySQL database using a Python script (details). Mostly are in Portuguese but if you are interest I can translate to English. If you found any problem dont’t hesitate to contact me in comments.]
Esse um pequeno lembrete para quem quer pegar o conceito de ponteiro rpido. to simples que nem programa direito voc vai precisar, s seguir sua intuio e o GDB ;-)
1. Bsico
Vamos comear com um cdigo muito simples.
#include 
int main(int argc, char *argv[]) {
int *ptr = NULL;
int variavel_A;
int variavel_B;
variavel_A = 5;
variavel_B = 18;
return 0;
}
</pre>
Usar o menor comando do GCC para compilar e linkar o programa. A sada (o executvel) chamar a.out, se voc quiser outro nome adicione "-o <nome>" no final do comando.
gcc -ggdb basico.c 
E iniciar o depurador, lembre-se que o texto em (vermelho)  comentrio e negrito  um comando para voc digiar na CLI (command-line interface) do GDB.
maluta@coding ~ $ gdb -q a.out
(gdb) l (lista o cdigo)
1       #include <stdio.h>
2
3 
4       int main(int argc, char *argv[]) {
5
6               int *ptr = NULL;
7               int variavel_A;
8               int variavel_B;
9
10              variavel_A = 5;
(gdb)
11              variavel_B = 18;
12
13              return 0;
14
15      }
(gdb) break 13  (inserir um breakpoint na linha 13)
Breakpoint 1 at 0x80483c6: file basico.c, line 13.
(gdb) r (run - inicia o programa)
Starting program: /home/maluta/a.out
Breakpoint 1, main () at basico.c:13
13              return 0;
(Mostra o que tem na variavel_A)
(gdb) print variavel_A
$1 = 5
(Mostra o que tem na variavel_B)
(gdb) print variavel_B
$2 = 18
(Imprime o contedo do endereo definido em ptr)
(gdb) print *ptr 
Cannot access memory at address 0x0 (ooops... essa no  uma posio vlida!)
(gdb) print ptr  (mas  claro que ptr guarda um valor...)
$3 = (int *) 0x0 (que  NULL)
(E qual o endereo da varivel_A?)
(gdb) print &variavel_A
$4 = (int *) 0xbfbc0ddc
(gdb) print *variavel_A (Podemos ver que no conseguimos acessar a variavel_A como um ponteiro pois ela guarda um endereo invlido)
Cannot access memory at address 0x5
(O endereo da varivel_B)
(gdb) print &variavel_B
$5 = (int *) 0xbfbc0de0
(Vamos fazer ptr apontar para a variavel_A)
(gdb) set ptr=0xbfbc0ddc 
(gdb) print *ptr (e mostrar o seu contedo)
$6 = 5
(Vamos fazer ptr apontar para a variavel_B)
(gdb) set ptr=&variavel_B
(gdb) print *ptr
$7 = 18
(gdb)
2. Intermedirio
Vamos dar mais um passo.
#include 
#include  /* malloc() */
#include  /* strncpy */
int main(int argc, char *argv[]) {
        char *nome;
        nome = malloc(10*sizeof(char));
        strncpy(nome,"tiago",5);
        return 0;
}
maluta@coding ~ $ gdb -q a.out
(gdb) l
1       #include <stdio.h>
2       #include <stdlib.h> /* malloc() */
3       #include <string.h> /* strncpy */
4       int main(int argc, char *argv[]) {
5
6
7               char *nome;
8
9               nome = malloc(10*sizeof(char));
10
(gdb) break 9
Breakpoint 1 at 0x8048421: file intermediario.c, line 9.
(gdb) r
Starting program: /home/maluta/a.out
Breakpoint 1, main () at basico.c:9
9               nome = malloc(10*sizeof(char));
(gdb) print nome
$1 = 0xb80b1190 "U\211WVS\207" (LIXO)
(gdb) n (next - executa a prxima instruo)
11              strncpy(nome,"tiago",5);
(gdb) n
15              return 0;
(gdb) print nome (texto copiado)
$2 = 0x804b008 "tiago"
(gdb) x/5x nome (conteudo em hexa)
0x804b008:      0x74    0x69    0x61    0x67    0x6f
(gdb) x/5c nome (conteudo em ascii)
0x804b008:      116 't' 105 'i' 97 'a'  103 'g' 111 'o'
(Vamos mudar a primeira letra da string)
(gdb) set {char}nome='T' 
(gdb) x/5x nome
0x804b008:      0x54    0x69    0x61    0x67    0x6f
(gdb) x/5c nome
0x804b008:      84 'T'  105 'i' 97 'a'  103 'g' 111 'o'
(Vamos colocar um espao em branco na segunda posio)
(gdb) set {char}(nome+1)=' ' (lembre-se que o ndice comea em zero)
(gdb) print nome
$11 = 0x804b008 "T ago"
(gdb) x/5x nome
0x804b008:      0x54    0x20    0x61    0x67    0x6f
(gdb) x/5c nome
0x804b008:      84 'T'  32 ' '  97 'a'  103 'g' 111 'o'
 (Voc pode ver o contedo da varivel com deslocamento 'offset')
(gdb) print nome+3
$17 = 0x804b00b "go"
Meu amigo Antnio (aka John) fez um exemplo do uso de classes em C, vamos utiliz-lo por aqui. Para mostrar o ponteiro para funo, s vou adicionar uma funo/mtodo subtraiMinhaClasse no cdigo.
#include 
struct MinhaClasse{
    int a;
    int b;
    int (*soma)();
};
int somaMinhaClasse(struct MinhaClasse *this){
    return (*this).a + (*this).b;
}
int subtraiMinhaClasse(struct MinhaClasse *this){
    return (*this).a - (*this).b;
}
void construtorMinhaClasse(struct MinhaClasse *this){
    this->soma = somaMinhaClasse;
}
int main(){
    int resposta;
    struct MinhaClasse objeto;
    construtorMinhaClasse(&objeto);
    objeto.a = 33;
    objeto.b = 15;
    resposta = objeto.soma();
    printf("%i",resposta);
return 0;
}
(gdb) break 34
Breakpoint 1 at 0x8048425: file john.c, line 34.
(gdb) r
Starting program: /home/maluta/a.out
Breakpoint 1, main () at john.c:34
29              printf("%i",resposta);
(Vamos ver o que tem na struct)
(gdb) print objeto
$1 = {a = 33, b = 15, soma = 0x80483d0 <somaMinhaClasse>}
(Bem como o valor contido em resposta)
(gdb) print resposta
$2 = 48
(Qual o endereo da funo somaMinhaClasse?)
(gdb) print somaMinhaClasse
$3 = {int (struct MinhaClasse *)} 0x80483d0 <somaMinhaClasse>
(Que interessante... objeto.soma e somaMinhaClasse tem o mesmo endereo?)
(gdb) print objeto.soma
$4 = (int (*)()) 0x80483d0 <somaMinhaClasse>
(E a funo subtraiMinha classe est sozinha?)
(gdb) print subtraiMinhaClasse
$5 = {int (struct MinhaClasse *)} 0x80483e3 <subtraiMinhaClasse>
(Que tal conect-la a algum?)
(gdb) set objeto.soma=subtraiMinhaClasse
(E lgico ver o resultado!)
(gdb) print objeto.soma()
$6 = 18
(O novo par de objeto.soma ;-))
(gdb) print objeto.soma
$8 = (int (*)()) 0x80483e3 <subtraiMinhaClasse>
(No gostei! Quero voltar para o que tinha antes)
(gdb) set objeto.soma=somaMinhaClasse
(gdb) print objeto.soma()
$9 = 48