2010-10-14 5 views
7

Vous essayez de comprendre ce que le pointeur de la fonction représente réellement? Est-ce l'adresse dans le segment de code où réside la fonction?Que représente la valeur du pointeur d'un pointeur de fonction?

Ex: ce morceau de code:

#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; 
} 

... imprime ceci:

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

Je suppose que je suis un peu confus avec la façon dont la pile exactement/tas d'un processus raconte avec le segment de données/segment de code ELF. Tout pointeur utile serait vraiment le bienvenu. Aussi, ma première question, alors s'il vous plaît soyez doux, j'essaie vraiment d'apprendre. Merci!

Répondre

5

C'est l'adresse du point d'entrée de la fonction - début de son code. La variable a est située sur la pile, donc pas de surprise, son adresse diffère de façon significative - la pile et le code sont assignés à des régions de code différentes qui peuvent être très éloignées.

+0

Droit, de sorte que la sortie ici représente l'emplacement où cette fonction particulière a été chargée dans le cadre du segment de code? Existe-t-il un moyen pour un programme C d'imprimer le segment de données, les segments de début/fin de segment de code? – helpmelearn

+0

@helpmelearn: Oui, c'est l'adresse où se trouve la fonction start. Je ne suis pas au courant d'une solution pour trouver les adresses de segments et je suppose que cela dépendrait de l'implémentation. Peut-être y at-il un programme d'utilité qui peut le faire pour n'importe quel processus. – sharptooth

3

Cette image du livre UNIX: Systems Programming devrait clarifier les choses.

En bas du diagramme, vous avez le texte de votre programme (adresses faibles). Comme peut être vérifié à partir de votre programme. C'est là que foo() résiderait.

alt text

2

Une chose à garder à l'esprit est que votre code est pas tout à fait conforme aux normes. Si vous utilisez gcc -Wall -Wextra -pedantic -ansi, vous obtiendrez une plainte concernant la ligne sur laquelle vous imprimez le pointeur de fonction. C'est parce que la norme ne garantit pas que les pointeurs de fonction peuvent être convertis en pointeurs vides. C est conçu pour fonctionner sur de nombreuses architectures différentes, et si l'architecture est une architecture de Harvard (instruction séparée et mémoire de données), il peut y avoir de bonnes raisons de rendre ces pointeurs de tailles différentes.

Je suppose que dans la pratique, il est peu probable, mais un bon factoid à connaître. Esp lorsque vous essayez d'apprendre les détails intimes de C.