2010-10-14 15 views
7

Cercando di capire cosa rappresenta effettivamente il puntatore alla funzione? È l'indirizzo nel segmento di codice in cui risiede la funzione?Che cosa rappresenta il valore del puntatore di un puntatore a funzione?

Per esempio: questo pezzo di codice:

#include <stdio.h> 

void foo(void) 
{ 
} 

int main(void) 
{ 
    int a = 10; 
    printf("a's address: %p\n", &a); 
    printf("foo's address: %p\n", foo); 
    return 0; 
} 

... stampe questo:

[sh/prog-exercises/adam]:./a.out 
a's address: 0xbfffb414 
foo's address: 0x8048430 

Credo che io sono un po 'confuso di come impilare esattamente/mucchio di un processo si riferisce con il segmento di dati ELF/segmento di codice. Qualsiasi suggerimento utile sarebbe davvero il benvenuto. Inoltre, la mia prima domanda, quindi per favore sii gentile, sto davvero cercando di imparare. Grazie!

risposta

5

Questo è l'indirizzo del punto di inserimento della funzione - avvio del codice. La variabile a si trova sullo stack, quindi non sorprende che il suo indirizzo differisca in modo significativo: stack e codice sono assegnati a regioni di codice diverse che possono essere abbastanza distanti tra loro.

+0

Giusto, quindi l'output qui rappresenta la posizione in cui questa particolare funzione è stata caricata come parte del segmento di codice? C'è un modo per un programma C per stampare il segmento dati, gli indirizzi inizio/fine segmento codice? – helpmelearn

+0

@helpmelearn: Sì, questo è l'indirizzo in cui si trova la funzione start. Non sono a conoscenza di una soluzione per trovare gli indirizzi dei segmenti e suppongo che dipenda dall'implementazione. Forse c'è qualche programma di utilità che può fare questo per qualsiasi processo. – sharptooth

3

Questa immagine del libro UNIX: Systems Programming dovrebbe chiarire le cose.

Nella parte inferiore dello schema è presente il testo del programma (indirizzi bassi). Come può essere verificato dal tuo programma. Ecco dove si troverebbe foo().

alt text

2

Una cosa da tenere a mente è che il codice non è del tutto conforme agli standard. Se si utilizza gcc -Wall -Wextra -pedantic -ansi, si riceverà un reclamo sulla riga in cui si stampa il puntatore della funzione. Questo perché lo standard non garantisce che i puntatori di funzione possano essere convertiti in puntatori void. C è progettato per funzionare su molte architetture diverse e, se l'architettura è un'architettura di Harvard (istruzioni separate e memoria dati), potrebbero esserci buone ragioni per rendere questi indicatori di dimensioni diverse.

Immagino che in pratica non sia probabile che contenga, ma un buon fattoide di cui essere consapevole. Esp quando stai cercando di imparare i dettagli intimi di C.

Problemi correlati