2017-09-19 5 views
0

Je suis en train d'explorer des pointeurs et je suis en train de jouer avec des pointeurs de structure en particulier. À l'heure actuelle, j'ai ce code:Confus au sujet de l'emplacement d'une structure en mémoire

#include <stdlib.h> 
#include <stdio.h> 

struct point{ 
double x; 
double y; 
}; 

int main(){ 
    char *pc; 
    int *pi; 
    struct point *pp; 

    //char pointer 
    printf("%p\n\n", (void*)pc); 
    pc++; 
    printf("%p\n\n", (void*)pc); 

    //int pointer 
    printf("%p\n\n", (void*)pi); 
    pi += 2; 
    printf("%p\n\n", (void*)pi); 

    //struct pointer 
    printf("%p\n\n", (void*)pp); 
    pp -= 3; 
    printf("%p\n\n", (void*)pp); 
} 

La sortie de ce code est la suivante:

0x104978036 

0x104978037 

0x7fff5ec4bbc8 

0x7fff5ec4bbd0 

0x0 

0xffffffffffffffd0 

Je comprends les 4 premières sorties, avec l'arithmétique des pointeurs char et int, mais je suis confus pourquoi il renvoie 0x0 pour l'adresse de la mémoire du pointeur struct? Aussi, si je voulais l'adresse de dire, double y en mémoire, comment pourrais-je imprimer cela?

+3

« Je comprends ... ». Non, vous ne le faites pas. Il n'y a rien à "comprendre" ici. Le comportement du code est complètement dénué de sens, car aucune des variables n'est initialisée. – AnT

+0

Ce que je veux dire, c'est que je comprends le saut de 36 à 37, et de bbc8 à bbd0 en raison de la taille d'un char et int, j'apprends encore C et je ne me rendais pas compte que c'était un comportement indéfini – krambo

Répondre

6

Votre code appelle Comportement non défini, puisque tous vos pointeurs sont utilisés uninitialized!

Compile avec des avertissements activés (par exemple -Wall pour GCC) et obtenir:

prog.c: In function 'main': 
prog.c:15:5: warning: 'pc' is used uninitialized in this function [-Wuninitialized] 
    printf("%p\n\n", (void*)pc); 
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~ 
prog.c:20:5: warning: 'pi' is used uninitialized in this function [-Wuninitialized] 
    printf("%p\n\n", (void*)pi); 
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~ 
prog.c:25:5: warning: 'pp' is used uninitialized in this function [-Wuninitialized] 
    printf("%p\n\n", (void*)pp); 
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~ 

Initialiser vos pointeurs comme celui-ci, par exemple:

char c = 'a'; 
char *pc = &c; 
int i = 5; 
int *pi = &i; 
struct point p; 
struct point *pp = &p; 

et pourrait obtenir:

0x7ffe629c90d7 // address of the charatcer 

0x7ffe629c90d8 // sizeof(char) is 1 

0x7ffe629c90d0 // address of the integer 

0x7ffe629c90d8 // sizeof(int) is 8 in this system 

0x7ffe629c90c0 // address of the struct 

0x7ffe629c9090 // sizeof(struct point) is 16 in this system 
// 0x7ffe629c90c0 - 0x7ffe629c9090 = 0x30 -> Decimal: 48 = 3 * 16 
+2

sur un pointeur 'NULL' (ou sur n'importe quel pointeur si vous sortez des limites, même sans déréférencement) est aussi UB. – o11c

+0

Y a-t-il une raison pour laquelle les types primitifs initialisés ont des valeurs indésirables alors que la structure est définie sur zéro? – Carl

+0

@Carl Je ne vois pas la structure à zéro. – gsamaras

4

Lorsque vous déclarez un pointeur, vous devez lui allouer de la mémoire ou le définir sur null si vous ne l'utilisez pas.

pc = malloc(sizeof(*pc)); 
pi = malloc(sizeof(*pi)); 
pp = malloc(sizeof(*pp)); 

N'oubliez pas de vérifier la valeur de retour de malloc !!!! (ne l'a pas fait exprès)

Vous devez compiler avec -W -Wall -Wextra -g, puis exécutez le binaire avec valgrind.

De plus, vous n'avez pas besoin de jeter pour annuler * car il est déjà un pointeur

Voici le résultat:

0xf88010 

0xf88011 

0xf88030 

0xf88038 

0xf88050 

0xf88020