IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Intérêts de l'utilisation des pointeurs dans certains cas


Sujet :

C

  1. #1
    Membre régulier
    Homme Profil pro
    ingénieur essais électronique
    Inscrit en
    Mai 2011
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur essais électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2011
    Messages : 144
    Points : 75
    Points
    75
    Par défaut Intérêts de l'utilisation des pointeurs dans certains cas
    Bonjour,

    Je me pose la questions suivante qui peut vous parraitre bête. J'ai bien compris l'utilisation des pointeurs dans certaine fonction précise (tableau, chaine de caractere etc...). Mais es ce correcte dans une utilisation comme la suivante :

    La logique serait de programmer comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int main()
    {
     
        int i=0;
     
        printf("valeur de i = %d\n",i);
     
        i++;
     
        printf("valeur de i = %d\n",i);
     
        return 0;
    }
    Mais pourquoi pas comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int main()
    {
     
        int *i;
     
        printf("valeur de i = %d\n",*i);
     
        *i+=1;// question subsidiare : pourquoi *i++ ne fonctionne pas ?
     
        printf("valeur de i = %d\n",*i);
     
        return 0;
    }
    Je suppose que la premiere methode est la mieux. Mais pourquoi pas la deuxieme ? Je sait que dans la deuxieme ecriture, on ne peut connaitre l'adresse du 1 mais uniquement celle de i. Mais y a t il autre chose.

    Merci

  2. #2
    Membre éclairé Avatar de Bayard
    Inscrit en
    Juin 2002
    Messages
    859
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 859
    Points : 714
    Points
    714
    Par défaut
    Dans la seconde solution vous déclarez un pointeur d'entier.
    Ce pointeur ne pointe nulle part. C'est comme si vous aviez un panneau indicateur routier et il n'y a rien écrit dessus.
    Si tu ne vis pas ce que tu penses alors tu penses ce que tu vis.

  3. #3
    Membre régulier
    Homme Profil pro
    ingénieur essais électronique
    Inscrit en
    Mai 2011
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur essais électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2011
    Messages : 144
    Points : 75
    Points
    75
    Par défaut
    Es ce que comme cela c'est mieux : pour moi on déclare un pointeur sur int puis on le défini à 1.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int main()
    {
        int *i;
     
        *i=1;
     
        printf("valeur de i = %d\n",*i);
     
        (*i)++;
     
        printf("valeur de i = %d\n",*i);
     
        return 0;
    }
    Pourquoi n'utilise t on pas cette écriture plutot que la premiere écriture (variable classique) de mon message de départ ?

  4. #4
    Membre éclairé Avatar de Bayard
    Inscrit en
    Juin 2002
    Messages
    859
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 859
    Points : 714
    Points
    714
    Par défaut
    Au niveau convention, je préférerais int *pi; que int *i; pour indiquer que c'est un pointeur.

    Là il n'y a rien écrit sur le panneau (pi ne vaut rien). Et il faut aller écrire 1 à une addresse inconnue.

    Est-ce que vous avez essayer d'exécuter cela ?
    Si tu ne vis pas ce que tu penses alors tu penses ce que tu vis.

  5. #5
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    - Définir un pointeur va créer un pointeur, mais pas l'objet pointé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int main(void)
    {
        int *i;  // création du pointeur
        int ii;  // création d'un entier
        i = ⅈ // placer l'adresse de l'entier dans le pointeur 
        *i=1;    // accéder à l'entier via le pointeur 
        printf("valeur de ii = %d\n",*i); 
        (*i)++; 
        printf("valeur de ii = %d\n",*i); 
        return 0;
    }
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  6. #6
    Membre éprouvé

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Points : 1 273
    Points
    1 273
    Par défaut
    Comme le dit Bayard, un pointeur est un panneau indicateur (vers un bloc de mémoire), il ne contient rien en lui-même. Il est donc inutilisable tant qu’il n’est pas initialisé avec une adresse mémoire valide (comprendre, qui a été allouée d’une façon ou d’une autre par/pour le programme).

    Assigner une valeur quelconque à un pointeur non-initialisé (comme le fait ton code) revient à essayer d’écrire à un emplacement aléatoire de la mémoire –*c’est l’erreur de segmentation assurée*!

    Il te faut donc d’abord initialiser ton pointeur, avant de le déréférencer, soit en lui assignant l’adresse d’une autre variable*:

    …soit en lui allouant de façon dynamique la mémoire nécessaire au type du pointeur*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int *pi = malloc(sizeof(int));
    (Ne pas oublier, dans ce dernier cas, de libérer cette mémoire une fois qu’on en a plus besoin, free(pi)…).

    Une bonne pratique consiste à toujours assigner la valeur NULL (l’adresse mémoire 0) à un pointeur qui n’est pas valide, cela permet de tester très simplement s’il l’est ou pas*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    int main() {
    	int *pi = NULL;
    	int i = 1;
     
    	if (pi)
    		printf("Valid int pointer (value: %d): %p\n", *pi, pi);
    	else
    		printf("NULL int pointer!\n");
     
    	pi = &i;
    	if (pi)
    		printf("Valid int pointer (value: %d): %p\n", *pi, pi);
    	else
    		printf("NULL int pointer!\n");
     
    	pi = malloc(sizeof(int));
    	/* Attention, malloc n'initialise pas la mémoire allouée, sa valeur est donc aléatoire! */
    	if (pi)
    		printf("Valid int pointer (value: %d): %p\n", *pi, pi);
    	else
    		printf("NULL int pointer!\n");
     
    	/* Et on n'oublie pas de libérer la mémoire! */
    	/* XXX Attention à ne pas faire ça si pi pointe sur une variable, c-à-d si la mémoire concernée n’a pas été allouée dynamiquement sur le tas (heap)! */
    	if (pi)
    		free(pi);
     
    	return 0;
    }
    Sinon, pour répondre à ta question (qui revient en gros à «*pourquoi préférer la syntaxe “variable” à la syntaxe “pointeur” quand c’est possible*»), et bien la réponse est simple*: parce que c’est plus simple*! Au lieu d’avoir à gérer deux informations dans le code (l’adresse et la valeur), on n’en a qu’une à gérer (la valeur), donc moins de gymnastique genre (*pi)++ (ou pire encore, *(pi++), side effects included!), donc code plus facile à lire, et moins de risques d’erreur*! Et puis c’est bien connu, la première qualité du programmeur est d’être paresseux*!

  7. #7
    Membre éclairé
    Avatar de Kirilenko
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 234
    Points : 807
    Points
    807
    Par défaut
    Bonjour,

    Citation Envoyé par sylv20 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *i+=1;// question subsidiare : pourquoi *i++ ne fonctionne pas ?
    L'opérateur ++ a une priorité supérieure à l'opérateur unaire *. L'expression *i++ est donc équivalente à *(i++), qui consiste à incrémenter le pointeur d'une unité (en l'occurrence, une unité vaut sizeof *i), puis à déréférencer l'adresse ainsi obtenue. J'imagine que tu souhaitais incrémenter la valeur contenue dans l'objet pointé par i, auquel cas il faut forcer les priorités grâce aux parenthèses (). (*i)++ semble être ce que tu souhaites : on déréférence le pointeur i, puis on incrémente la valeur de l'objet référencé. Note que *i += 1 fonctionne pour les mêmes raisons : l'opérateur * a une priorité supérieure à l'opérateur +=. Pour faire le même type de raisonnement à l'avenir, tu peux trouver quelques tableaux de priorité des opérateurs en recherchant « operator precedence C » sur ton moteur de recherche préféré. Cette page correspond par exemple à ce que tu peux utiliser comme référence.

    Bonne journée !
    Récursivité en C : épidémie ou hérésie ?

    "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman

  8. #8
    Membre régulier
    Homme Profil pro
    ingénieur essais électronique
    Inscrit en
    Mai 2011
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur essais électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2011
    Messages : 144
    Points : 75
    Points
    75
    Par défaut
    Citation Envoyé par Bayard Voir le message
    Au niveau convention, je préférerais int *pi; que int *i; pour indiquer que c'est un pointeur.

    Là il n'y a rien écrit sur le panneau (pi ne vaut rien). Et il faut aller écrire 1 à une addresse inconnue.

    Est-ce que vous avez essayer d'exécuter cela ?
    Oui j'ai essayer d'executer ce code. Il fonctionne mais comme je l'ai compris, ce n'est conforme à l'utilisation des pointeurs.

  9. #9
    Membre régulier
    Homme Profil pro
    ingénieur essais électronique
    Inscrit en
    Mai 2011
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur essais électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2011
    Messages : 144
    Points : 75
    Points
    75
    Par défaut
    Citation Envoyé par mont29 Voir le message
    Comme le dit Bayard, un pointeur est un panneau indicateur (vers un bloc de mémoire), il ne contient rien en lui-même. Il est donc inutilisable tant qu’il n’est pas initialisé avec une adresse mémoire valide (comprendre, qui a été allouée d’une façon ou d’une autre par/pour le programme).

    Assigner une valeur quelconque à un pointeur non-initialisé (comme le fait ton code) revient à essayer d’écrire à un emplacement aléatoire de la mémoire –*c’est l’erreur de segmentation assurée*!

    Il te faut donc d’abord initialiser ton pointeur, avant de le déréférencer, soit en lui assignant l’adresse d’une autre variable*:

    …soit en lui allouant de façon dynamique la mémoire nécessaire au type du pointeur*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int *pi = malloc(sizeof(int));
    (Ne pas oublier, dans ce dernier cas, de libérer cette mémoire une fois qu’on en a plus besoin, free(pi)…).

    Une bonne pratique consiste à toujours assigner la valeur NULL (l’adresse mémoire 0) à un pointeur qui n’est pas valide, cela permet de tester très simplement s’il l’est ou pas*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    int main() {
    	int *pi = NULL;
    	int i = 1;
     
    	if (pi)
    		printf("Valid int pointer (value: %d): %p\n", *pi, pi);
    	else
    		printf("NULL int pointer!\n");
     
    	pi = &i;
    	if (pi)
    		printf("Valid int pointer (value: %d): %p\n", *pi, pi);
    	else
    		printf("NULL int pointer!\n");
     
    	pi = malloc(sizeof(int));
    	/* Attention, malloc n'initialise pas la mémoire allouée, sa valeur est donc aléatoire! */
    	if (pi)
    		printf("Valid int pointer (value: %d): %p\n", *pi, pi);
    	else
    		printf("NULL int pointer!\n");
     
    	/* Et on n'oublie pas de libérer la mémoire! */
    	/* XXX Attention à ne pas faire ça si pi pointe sur une variable, c-à-d si la mémoire concernée n’a pas été allouée dynamiquement sur le tas (heap)! */
    	if (pi)
    		free(pi);
     
    	return 0;
    }
    Sinon, pour répondre à ta question (qui revient en gros à «*pourquoi préférer la syntaxe “variable” à la syntaxe “pointeur” quand c’est possible*»), et bien la réponse est simple*: parce que c’est plus simple*! Au lieu d’avoir à gérer deux informations dans le code (l’adresse et la valeur), on n’en a qu’une à gérer (la valeur), donc moins de gymnastique genre (*pi)++ (ou pire encore, *(pi++), side effects included!), donc code plus facile à lire, et moins de risques d’erreur*! Et puis c’est bien connu, la première qualité du programmeur est d’être paresseux*!
    Je comprend bien votre réponse et je vous en remercie.

    Par contre, dans ce code, il y a une morceau que je ne comprend pas :

    Les premisers printf indique que le pointeur n'est pas assigné.
    Les deuxieme printf indique que le pointeur possede l'adresse de i et pointe sur i. L'adresse du pointeur et sa taille sont automatique.

    C'est là que ce se complique.

    Je ne voit pas bien ce que fait le malloc.
    Pour moi il définit un nouvel emplacement mémoire pour pi. (da la taille d'un int).
    Du coup l'ancien emplacement mémoire n'exsite plus et le pointeur pi ne pointe plus sur rien. C'est juste un emplcement fixe défini.

    Pouvez vous me confirmer ou non ce que j'ai compris ?

    Merci

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 371
    Points : 23 626
    Points
    23 626
    Par défaut
    Hello,


    Citation Envoyé par sylv20 Voir le message
    Je ne voit pas bien ce que fait le malloc.
    Pour moi il définit un nouvel emplacement mémoire pour pi. (da la taille d'un int).
    Du coup l'ancien emplacement mémoire n'exsite plus et le pointeur pi ne pointe plus sur rien. C'est juste un emplcement fixe défini.

    Pouvez vous me confirmer ou non ce que j'ai compris ?
    Non. Ça, ce serait un comportement calqué du Java. Ça simplifie la vie quand on programme au quotidien mais quand on commence par cela, ça induit des lacunes qu'il est difficile de combler ensuite.

    « malloc() » se contente de demander au système de réserver de la place en mémoire. Ça te garantit que personne d'autre (en principe) ne va écrire dedans et gère également, si nécessaire, les droits d'accès lorsque tu travailles sur des systèmes utilisant un mode protégé, ce qui est pour ainsi dire toujours le cas aujourd'hui. Une fois que c'est fait, la fonction te renvoie l'emplacement (donc l'adresse) de la zone de mémoire qu'elle t'a allouée.

    Comme cette fonction te renvoie un pointeur, il te faut une variable de type « pointeur » pour l'enregistrer. Puisque tu utilises « = », le contenu antérieur de cette variable est écrasé. De là, tu as trois possibilités :

    — Soit cette variable n'avait jamais été initialisée, et donc on se fiche de ce qu'il y avait dedans ;
    — Soit cette variable contenait l'adresse d'un objet statique comme ta variable « i », obtenue avec « &i » ;
    — Soit cette variable contenait l'adresse d'une zone réservée avec malloc() et là, c'est ennuyeux parce que le pointeur est complètement décorrélé des appels systèmes. Cette zone, il faut demander au système de la libérer quand tu ne t'en sers plus avec free(). C'est donc une source fréquente de fuite mémoire.

    C'est un peu comme si tu réservais une consigne dans une gare et que tu notais son numéro et son code sur un morceau de papier. Si tu égares ce morceau ou si tu t'en débarrasses volontairement, ça ne va pas automatiquement libérer le casier de la consigne. Au contraire, si tu ne te souviens plus de ce qui y était écrit, le casier risque de rester occupé pendant très… très longtemps ! :-)

  11. #11
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    @Obsidian : belle réponse

    @sylv20 :
    Je suppose que la premiere methode est la mieux. Mais pourquoi pas la deuxieme
    et pour revenir sur ta question "l'intérêt des pointeurs dans certains cas".

    Dans le cas que tu montres, la solution 2 (corrigée notamment par diogene) n'a pas d'utilité puisque tu as un accès direct à l'objet.

    De manière générale, on va dire que tant qu'on peut se passer des pointeurs, alors on s'en passe. Si on en a besoin, alors on les utilise. Les pointeurs ne sont que des conteneurs d'adresses d'autres variables. Utiliser un pointeur pour travailler sur un objet auquel on a accès directement ne sert à rien à part compliquer la tâche (utilisation de *) ; utiliser un pointeur pour travailler sur un objet auquel on ne peut pas avoir accès directement est incontournable. Exemple ? Dans une fonction. Si tu veux modifier un objet dans une fonction, tu dois passer l'adresse de cet objet (donc, très schématiquement, un pointeur) pour le retrouver dans la mémoire.

  12. #12
    Membre régulier
    Homme Profil pro
    ingénieur essais électronique
    Inscrit en
    Mai 2011
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur essais électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2011
    Messages : 144
    Points : 75
    Points
    75
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Hello,




    Non. Ça, ce serait un comportement calqué du Java. Ça simplifie la vie quand on programme au quotidien mais quand on commence par cela, ça induit des lacunes qu'il est difficile de combler ensuite.

    « malloc() » se contente de demander au système de réserver de la place en mémoire. Ça te garantit que personne d'autre (en principe) ne va écrire dedans et gère également, si nécessaire, les droits d'accès lorsque tu travailles sur des systèmes utilisant un mode protégé, ce qui est pour ainsi dire toujours le cas aujourd'hui. Une fois que c'est fait, la fonction te renvoie l'emplacement (donc l'adresse) de la zone de mémoire qu'elle t'a allouée.

    Comme cette fonction te renvoie un pointeur, il te faut une variable de type « pointeur » pour l'enregistrer. Puisque tu utilises « = », le contenu antérieur de cette variable est écrasé. De là, tu as trois possibilités :

    — Soit cette variable n'avait jamais été initialisée, et donc on se fiche de ce qu'il y avait dedans ;
    — Soit cette variable contenait l'adresse d'un objet statique comme ta variable « i », obtenue avec « &i » ;
    — Soit cette variable contenait l'adresse d'une zone réservée avec malloc() et là, c'est ennuyeux parce que le pointeur est complètement décorrélé des appels systèmes. Cette zone, il faut demander au système de la libérer quand tu ne t'en sers plus avec free(). C'est donc une source fréquente de fuite mémoire.

    C'est un peu comme si tu réservais une consigne dans une gare et que tu notais son numéro et son code sur un morceau de papier. Si tu égares ce morceau ou si tu t'en débarrasses volontairement, ça ne va pas automatiquement libérer le casier de la consigne. Au contraire, si tu ne te souviens plus de ce qui y était écrit, le casier risque de rester occupé pendant très… très longtemps ! :-)
    Oui en effet, je voit ce que tu veux dire. Cependant, lorsque j'execute le code de mont29, voila le resultat :

    premier printf :
    NULL int pointer => c'est normal

    deuxieme printf :
    valid int pointer (value : 1) : 0028FF18 => normal aussi, pi pointe sur i. On recupere la valeur pointée et l'adresse de i

    troisieme printf (après le malloc) :
    Valid int pointer (value : 7475240) : 00720FB0 => pour moi on écrase la valeur de pi (anciennement adresse de i : 0028FF18) et on met l'adresse d'un bloc de taille int commancant à l'adresse 00720FB0 qui contient déjà la valeur 7475240.

    En suite j'ai complété le code par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    *pi=2;
     
        	if (pi)
    		printf("Valid int pointer (value: %d): %p\n", *pi, pi);
    	else
    		printf("NULL int pointer!\n");
    Ce quatrieme printf donne :
    Valid int pointer (value 2) : 00720FB0 => on a changer la valeur du bloc int à l'adresse 00720FB0

    Au final pi pointe sur une autre adresse.

    Mon analyze est elle correcte ?

  13. #13
    Membre éprouvé

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Points : 1 273
    Points
    1 273
    Par défaut
    Oui, bien sûr.

    Mais ici, ce n’est pas un problème, car l’adresse de i n’est pas “perdue” dans les limbes du programme lorsque l’adresse retournée par malloc() est assignée à pi*: elle est toujours “liée” (dans la portée de main()) à cette valeur i. C’est le compilateur qui se charge de réserver la mémoire nécessaire à i à l’entrée de la fonction main(), et de la libérer à sa sortie (pour simplifier les choses).

    Il faut bien distinguer adresse et valeur. Écraser la valeur d’un pointeur signifie que celui-ci ne pointe plus sur la même zone de mémoire, et c’est tout. Cela n’affecte en rien ni l’ancienne, ni la nouvelle zone de mémoire.

  14. #14
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 371
    Points : 23 626
    Points
    23 626
    Par défaut
    Citation Envoyé par sylv20 Voir le message
    troisieme printf (après le malloc) :
    Valid int pointer (value : 7475240) : 00720FB0 => pour moi on écrase la valeur de pi (anciennement adresse de i : 0028FF18) et on met l'adresse d'un bloc de taille int commancant à l'adresse 00720FB0 qui contient déjà la valeur 7475240.

    En suite j'ai complété le code par :
    Ce quatrieme printf donne :
    Valid int pointer (value 2) : 00720FB0 => on a changer la valeur du bloc int à l'adresse 00720FB0

    Au final pi pointe sur une autre adresse.

    Mon analyze est elle correcte ?
    Ben non, relis bien tes exemples : tu as effectivement modifié le contenu de la zone de mémoire pointée mais l'adresse de celle-ci est bien resté la même.

  15. #15
    Membre régulier
    Homme Profil pro
    ingénieur essais électronique
    Inscrit en
    Mai 2011
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur essais électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2011
    Messages : 144
    Points : 75
    Points
    75
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Ben non, relis bien tes exemples : tu as effectivement modifié le contenu de la zone de mémoire pointée mais l'adresse de celle-ci est bien resté la même.
    Ah non, je me suis mal exprimé. Quand j'ai mis "Au final pi pointe sur une autre adresse." c'est entre le deuxieme et le troisieme printf, c'est a dire entre :

    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pi = malloc(sizeof(int));

  16. #16
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 371
    Points : 23 626
    Points
    23 626
    Par défaut
    Citation Envoyé par sylv20 Voir le message
    Ah non, je me suis mal exprimé. Quand j'ai mis "Au final pi pointe sur une autre adresse." c'est entre le deuxieme et le troisieme printf
    Dans ce cas, oui, je pense que as bien compris le principe.

Discussions similaires

  1. Réponses: 0
    Dernier message: 18/04/2014, 14h47
  2. [SP-2010] Croix rouges à la place des images, dans certains cas.
    Par sebfreu dans le forum SharePoint
    Réponses: 5
    Dernier message: 26/03/2012, 12h01
  3. [VB.NET] Utilisation des sessions dans Session_End ?
    Par San Soussy dans le forum ASP.NET
    Réponses: 2
    Dernier message: 02/02/2005, 16h40
  4. Utilisation des nombres dans Winsock2
    Par DeusXL dans le forum MFC
    Réponses: 14
    Dernier message: 01/12/2004, 17h36
  5. Utilisation de Pointeurs dans API windows
    Par Drooxy dans le forum API, COM et SDKs
    Réponses: 4
    Dernier message: 13/03/2003, 22h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo