Comment déclarer proprement des pointeurs

Comment déclarer proprement des pointeurs - C - Programmation

Marsh Posté le 27-11-2005 à 16:22:05    

Bonjour,
 
je viens de m'apercevoir qu'intervertir l'ordre de deux déclarations de pointeurs peut créer des erreurs de segmentation
 

Code :
  1. // cette déclaration marche
  2. char** ptablo;
  3. int* pmutexId;
  4. //celle-ci provoque un seg_fault dans la suite du programme
  5. int* pmutexId;
  6. char** ptablo;


 
Je crois avoir compris que le problème est qu'aucun emplacement n'est réservé pour stocker la valeur pointée par char** (une adresse).
Est-ce que je suis obligé de faire un malloc() après chaque déclaration de pointeur ?
 
D'autre part, en prenant un exemple simple, est-ce que  

Code :
  1. int* p;
  2. *p=14;

est correct ? ou y'a t-il toujours un risque de seg_fault ?

Reply

Marsh Posté le 27-11-2005 à 16:22:05   

Reply

Marsh Posté le 27-11-2005 à 16:40:13    

comportement indéfini.

Reply

Marsh Posté le 27-11-2005 à 16:54:50    

c'est donc une erreur de programmation ?

Reply

Marsh Posté le 27-11-2005 à 16:58:14    

Code :
  1. int *p=NULL;


 
ça te forcera à faire une allocation par la suite avant de pouvir utiliser ton pointeur ;)

Reply

Marsh Posté le 27-11-2005 à 18:21:23    

frankie_flowers a écrit :

je viens de m'apercevoir qu'intervertir l'ordre de deux déclarations de pointeurs peut créer des erreurs de segmentation


Le problème est ailleurs. Si tu définis des pointeurs sans leur donner une valeur valide, le déréférencement produit un comportement indéfini. C'est un bug de codage.
 

Citation :

Je crois avoir compris que le problème est qu'aucun emplacement n'est réservé pour stocker la valeur pointée par char** (une adresse).


Oui. Le pointeur pointe n'importe où.

Citation :

Est-ce que je suis obligé de faire un malloc() après chaque déclaration de pointeur ?


Non. Ce qui est obligatoire, c'est que la valeur du pointeur soit valide au momement où tu l'utilises (ou si tu le passes à une fonction).

Citation :


D'autre part, en prenant un exemple simple, est-ce que  

Code :
  1. int* p;
  2. *p=14;

est correct ? ou y'a t-il toujours un risque de seg_fault ?


14 ça veut dire quoi ? Tu trouves que ça ressemble à une adresse valide ?
p n'étant pas défini, le comportement est indéfini. C'est un bug. Oui, il y a de risque de seg_fault.
 
Il y a 4 façons standards d'initialiser un pointeur
 

  • NULL (le pointeur est alors invalide, son déréférencement invoque un comporetement indéfini). Mais c'est une valeur testable  

if (p != NULL) ...


  • l'adresse d'une variable du même type
  • la valeur retournée par malloc()
  • la valeur retournée par fopen() (de type FILE*)


plus les variantes dérivées de ces exemples...

Message cité 1 fois
Message édité par Emmanuel Delahaye le 28-11-2005 à 11:35:33

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 27-11-2005 à 20:09:24    

Tu as du mal à finir ton TP de SDE ? :D

Reply

Marsh Posté le 28-11-2005 à 09:17:50    

frankie_flowers a écrit :

Bonjour,
 
Est-ce que je suis obligé de faire un malloc() après chaque déclaration de pointeur ?


 
Non. Mais chaque fois que tu déclares un pointeur style "<type> *pt"; tu es obligé d'écrire quelque part "pt=...<une adresse valide>..." avant de t'occuper de "*pt".
 
Donc si tu déclares un pointeur double style "<type> **pt"; il faut d'abord que t'écrives qqpart "pt=...<une adresse valide>..." avant d'aller t'occuper de "*pt" qui devra lui aussi recevoir "...<une adresse valide>..." avant que t'ailles t'occuper de "**pt".
 
Etc etc
 
La fonction "malloc()" alloue une zone mémoire et renvoie l'adresse de la zone allouée. Donc "malloc()" renvoie une adresse valide et c'est pourquoi on peut écrire "pt=malloc(...)". Mais c'est pas la seule façon d'y mettre une  adresse valide.
On peut aussi écrire "int i; int *pt; pt=&i"
 
La seule constante, c'est qu'il y a toujours écrit quelque part "pt=..."

Message cité 1 fois
Message édité par Sve@r le 28-11-2005 à 09:26:18

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 28-11-2005 à 11:22:07    

Emmanuel Delahaye a écrit :


14 ça veut dire quoi ? Tu trouves que ça ressemble à une adresse valide ?


 
il a ecrit
 
*p = 14;
 
pas  
 
p = 14;
 
(noob)
 

Reply

Marsh Posté le 28-11-2005 à 11:23:12    

'fin c'est faux quand même, puisque p est indéfini à cet endroit du programme :o

Reply

Marsh Posté le 28-11-2005 à 11:23:42    

Sve@r a écrit :


 
La seule constante, c'est qu'il y a toujours écrit quelque part "pt=..."


 
 

Code :
  1. int p, *pp, *ppp;
  2. ppp = &pp;
  3. *ppp = &a;
  4. *pp = 12;


 
(nan rien, c'est juste pour faire mon chieur)

Reply

Marsh Posté le 28-11-2005 à 11:23:42   

Reply

Marsh Posté le 28-11-2005 à 11:33:14    

chrisbk a écrit :

il a ecrit

*p = 14;


pas  

p = 14;




Ok. Je me suis laissé emporté... Corrigé.


Message édité par Emmanuel Delahaye le 28-11-2005 à 11:36:09

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 28-11-2005 à 12:42:02    

Citation :

Code :
 
     int p, *pp, *ppp;
     
     ppp = &pp;
     *ppp = &a;
     *pp = 12;
 


 
soit le code

Code :
  1. /*      essai2.c        */
  2. #include <stdio.h>
  3. int main (int argc, char *argv[])
  4. {
  5.         int     p, *pp, *ppp;
  6.         ppp = &pp;
  7.         *ppp = &p;
  8.         *pp = 12;
  9. }


 
on compile et on exécute
fronsac:18> gcc -o essai2 essai2.c
essai2.c: Dans la fonction « main »:
essai2.c:9: AVERTISSEMENT: affectation d'un type pointeur incompatible
essai2.c:10: AVERTISSEMENT: affectation transforme en entier un pointeur sans transtypage
fronsac:19> essai2
 
effectivement ça ne plante pas mais je doute que cela face quelque chose d'interessant et d'utile.
de plus a mon avis pp n'est toujours pas initialisé.
il est possible que dans l'élan une coquille ce soit glissé malicieusement et qu'il fallait lire **ppp
 

Reply

Marsh Posté le 28-11-2005 à 12:50:09    

Ok, je crois que j'ai bien compris le principe :jap:

Reply

Marsh Posté le 28-11-2005 à 13:41:28    

ué j'ai oublié une etoile, j'etais pas tres reveille [:petrus75]

Reply

Marsh Posté le 28-11-2005 à 13:57:00    

chrisbk a écrit :

Code :
  1. int p, *pp, **ppp;
  2. ppp = &pp;
  3. *ppp = &p;
  4. *pp = 12;


 
(nan rien, c'est juste pour faire mon chieur)


 
Bon, c'est vrai, tu as trouvé un exemple où on peut avoir *pp sans avoir pp=...
Mais en fait, tu masques l'instruction pp=&p en utilisant *ppp qui correspond à pp
Dans les faits... c'est comme si t'avais écrit pp=&p... sauf qu'il faut bien examiner le code pour s'en rendre compte.
 
Ceci démontre qu'on peut toujours pondre un code correct mais réellement illisible.
 

Reply

Marsh Posté le 28-11-2005 à 14:00:39    

oué chui fan de trucs porcho, j'adore parsemer mon code de machin comme ca pour faire rire mes collegues :
 

Code :
  1. typedef struct  prout
  2. {
  3. char *a,*b;
  4. }prout;
  5. prout youpi;
  6. unsigned char **yargla = (unsigned char **) &youpi,
  7. yargla [1] = "yogoto";


Message édité par chrisbk le 28-11-2005 à 14:43:03
Reply

Marsh Posté le 28-11-2005 à 14:39:51    

[:le poney de mr pink]

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed