Léa-Linux & amis :   LinuxFR   GCU-Squad   GNU
Probleme de realloc sur un tableau 2d.
Envoyé par: selox

Bonjour, j'ai un probleme sur la fonction realloc.

J'ai un tableau de char dynamique à deux dimensions :

char **creer_grille(int col,int lignes) {  int i,j; char **p4=malloc(lignes*sizeof(*p4)); if(p4==NULL) { printf("L'allocation n'a pas march\n"); exit(EXIT_FAILURE); }  for(i=0;i<lignes;i++) {  p4=malloc(col*sizeof(p4)); if(p4==NULL) { printf("L'allocation n'a pas march\n"); exit(EXIT_FAILURE); } }  for(i=0;i<lignes;i++)  for(j=0;j<col;j++) p4[j]=' ';   return p4; }


J'ai une fonction 'placerpion' qui lorsque la colonne choisie par l'utilisateur est remplie, on ajoute 10 lignes au tableau (via la fonction realloc).

Mais ça me fait toujours un segmentation fault lors de l'execution, et je ne vois pas trop d'où vient le probleme...

 void placerpion(char **p4,int colonnes,int lignes,char *joueuractuel) {
 
    int choixcol,i,j;
    
    if(*joueuractuel=='X' || *joueuractuel=='O') {
       
       printf("Choisissez la colonnes o vous voulez placer votre pion : ");
       scanf("%d",&choixcol);
       
       if(p4[(lignes-1)][choixcol] != ' ') {   /* Si colonne remplie, alors allouer 10 lignes de + */
          realloc(p4,(lignes+=10)*sizeof(p4));
          for(i=(lignes-10);i<lignes;i++)
             p4=malloc(colonnes*sizeof(p4)); 
      
       for(i=(lignes-10);i<lignes;i++) {       /* on remplit les nouvelles lignes de ' ' */
          for(j=0;j<colonnes;j++) 
             p4[j]=' '; } }
       
    
       for(i=0;i<lignes;i++)  /* Placer le pion du joueur à la case voulue */
          if(p4[choixcol] == ' ') { 
             p4[choixcol]=*joueuractuel; 
             break; } } }

Merci d'avance

Poste le Thursday 7 June 2007 00:45:16
Répondre     Citer    
Re: Probleme de realloc sur un tableau 2d.
Envoyé par: Fanch

porcassou !
tu créées p4 sur la stack ! c'est normal que ça explose !

int
creer_grille(int pi_col, int pi_lignes, char** po_grille)
{
  // bla bla bla en remplaçant p4 par po_grille
  // et en retournant 0 si tout va bien, -1 en cas d'erreur
}

en gros : tu veux utiliser p4 en dehors de la fonction, il ne faut donc pas le déclarer dans la fonction mais à l'extérieur de cette dernière, sinon la référence à p4 est créée sur la stack et non sur le heap du coup => boum.

Règle :
On ne déclare dans une fonction que des éléments qui ne sont utilisés QUE dans cette fonction. Tout le reste est paramètre ou variable globale.

------- <br />
La meilleure façon de prédire le futur, c'est de l'inventer ~ Alan Kay

Poste le Friday 8 June 2007 12:00:07
Répondre     Citer    
Re: Probleme de realloc sur un tableau 2d.
Envoyé par: Sve@r

Citation
Fanch
porcassou !
tu créées p4 sur la stack ! c'est normal que ça
explose !

en gros : tu veux utiliser p4 en dehors de la
fonction, il ne faut donc pas le déclarer dans la
fonction mais à l'extérieur de cette dernière,
sinon la référence à p4 est créée sur la stack et
non sur le heap du coup => boum.
Absolument pas !!! Où as-tu appris le C ???
p4 est alloué via malloc donc cela ne se passe absolument pas dans la pile !!! Sinon comment on ferait pour créer des fonctions qui allouent des objets et renvoient un pointeur sur l'objet alloué !!!

Citation
Fanch
Règle :
On ne déclare dans une fonction que des éléments
qui ne sont utilisés QUE dans cette fonction. Tout
le reste est paramètre ou variable globale.
Ben justement, p4 est un paramètre !!! Quand à conseiller d'introduire du global je me demande qui est le plus porcassou !!!

Citation
selox
Bonjour, j'ai un probleme sur la fonction
realloc.
Non, t'as un problème de compréhension pour une fonction qui doit modifier les variables qu'elle reçoit. Je t'explique: dans ta fonction "placerpion", tu fais une modification de "p4". Or "p4" est, dans le programme principal, un "char **". Et la règle est que si une fonction doit modifier une variable extèrieure, elle doit recevoir l'adresse de cette variable qui sera stockée dans un pointeur sur le type de la variable
Exemple: Une fonction qui modifie un "int"
void modif(int *pt_a_modifier)
{
    (*pt_a_modifier)=(*pt_a_modifier) + 1
}
Et son appel
int var=12;
modif(&var):

Tu as compris le principe ? Tu dois modifier un "int" tu passes l'adresse de ce "int" qui sera stocké dans un "int *". Or, toi tu veux modifier un "char **p4". Tu dois donc passer l'adresse de "p4" qui sera stocké dans un "char ***"

Trois petites remarques:
- la fonction "realloc" a pour but d'agrandir une zone. Elle est donc suceptible de déplacer le contenu de la zone dans une autre partie de la mémoire si la mémoire actuelle n'est pas suffisante. C'est pour ça qu'on passe à realloc le pointeur sur la zone à agrandir => afin qu'elle sache quoi déplacer. Mais comme la fonction renvoie un pointeur sur la nouvelle zone, il est nécessaire de récupérer ce pointeur => autrement dit, la syntaxe de realloc est la suivante
pt4=realloc(pt4, <nouvelle_taille>)
- (ligne+=10)*sizeof => non seulement compacter les instructions ne fait pas aller plus vite mais en plus ça complique la relecture => fais donc d'abord "ligne+=10" puis "realloc(pt4, ligne * ...)
- je te conseillerais d'inclure ton "p4" dans une jolie petite structure. Tout d'abord tu pourras y ajouter aussi tes joueurs et donc réduire tes paramètres (la fonction qui reçoit la structure reçoit à la fois p4 et les joueurs) et en plus ça te simplifiera la vie au niveau des pointeurs (tu seras pas obligé de jouer avec des "char ***p4")...


tu crois vraiment que ça te fera aller plus vite si tu compactes
reçoit un pointeur sur la zone à réallouer afin qu'elle sache quoi recopier si elle

L'homme qui murmurait à l'oreille des pingouins
[fr.lang.free.fr]

Poste le Friday 29 June 2007 22:24:51
Répondre     Citer    
Re: Probleme de realloc sur un tableau 2d.
Envoyé par: Fanch

eh ho t'es qui là, sombre héros ! on se calme !

Effectivement malloc crée jamais sur la pile mais dans le tas, ok j'ai eu un coup de chaud (et j'admets qu'en me relisant c'est complètement con, j'ai dû répondre à fond de boite entre 2 réunions ; mais que le premier qui n'a jamais écrit de connerie me jette la première pierre ...).

Toutefois la règle que j'ai donné, j'y tiens et je la maintiens. Mais bon, ça après, c'est de la philo (c'est comme goto, malloc quand y'en a pas besoin etc etc ...). }-)



------- <br />
La meilleure façon de prédire le futur, c'est de l'inventer ~ Alan Kay

Poste le Monday 2 July 2007 09:42:24
Répondre     Citer    
Re: Probleme de realloc sur un tableau 2d.
Envoyé par: farfati

Moi ce que je ne comprends pas c'est ça :
realloc(p4,(lignes+=10)*sizeof(p4))
Du genre faire
my_p = calloc( 1000, sizeof(my_p) )
Bizarre...
Normalement dans ce cas on fait
my_p = calloc( 1000, sizeof *my_p )
:-/

Poste le Tuesday 3 July 2007 14:42:31
Répondre     Citer    
Re: Probleme de realloc sur un tableau 2d.
Envoyé par: farfati

p4=malloc(colonnes*sizeof(p4));
Encore plus bizarre : p4 est de type char* , p4 de type char**. Il n'y a pas quelque chose qui ne va pas? #%b

p4=malloc(sizeof(**p4) * colonnes);
ne serait pas plus correct? yawning smiley)


Poste le Tuesday 3 July 2007 14:46:50
Répondre     Citer    
Re: Probleme de realloc sur un tableau 2d.
Envoyé par: Sve@r

Citation
Fanch
eh ho t'es qui là, sombre héros ! on se calme !
Ben tu me connais, on a déjà parlé ensemble !!! deye rolling smiley

Citation
Fanch
Effectivement malloc crée jamais sur la pile mais dans le tas, ok j'ai eu un coup de chaud (et j'admets qu'en me relisant c'est complètement con, j'ai dû répondre à fond de boite entre 2 réunions ; mais que le premier qui n'a jamais écrit de connerie me jette la première pierre ...).
Ah ben oui, parfois on parle en dormant, parfois on écrit des conneries entre 2 réunions mais c'est la vie ^^D-*

Citation
Fanch
Toutefois la règle que j'ai donné, j'y tiens et je
la maintiens.
Disons que ta règle est un court résumé des règles générales de programmation C (peut-être un peu trop court pour celui qui n'a jamais programmé en C et qui n'a donc jamais affronté le danger du pointeur devenu fou). Mais un bon programmeur suit les règles, un programmeur brillant les transgresse parfois... ;-)

Citation
farfati
p4=malloc(colonnes*sizeof(p4));Encore plus bizarre
: p4 est de type char* , p4 de type char**. Il n'y
a pas quelque chose qui ne va pas?

p4=malloc(sizeof(**p4) * colonnes);ne serait pas
plus correct?

Totalement exact. Cela confirme mon idée première, à savoir que seelox s'est complètement pommé dans ses pointeurs et qu'il devrait encapsuler ça dans une jolie structure ce qui lui éviterait de jongler avec des char *** (car cela va arriver...)


L'homme qui murmurait à l'oreille des pingouins
[fr.lang.free.fr]

Poste le Tuesday 3 July 2007 21:40:47
Répondre     Citer    
Re: Probleme de realloc sur un tableau 2d.
Envoyé par: Fanch

Sve@r : c'était pour le jeu de mots, rapport à mon coup de fatigue #%b


pour la règle, en l'occurrence c'est pour éviter des memory leaks du genre :
void toto() {
    char *p = NULL ;
    p = malloc(500) ;
    return ;
}


d'où (à postériori) mon coup de fatigue, je devais être en train de régler des problèmes de namespace sur du c++ :-/

------- <br />
La meilleure façon de prédire le futur, c'est de l'inventer ~ Alan Kay

Poste le Wednesday 4 July 2007 07:53:30
Répondre     Citer    

Veuillez vous authentifier auparavant pour commenter.

 

Ce forum !
Probleme de realloc sur un tableau 2d.
Pour poser vos questions sur les scripts shell, le Perl, le C, etc... Attention : nous ne sommes pas des spécialistes du dev, ce forum est juste pour de petites aides ponctuelles concernant le développement et les outils de développement.

Sauf mention contraire, les documentations publiées sont sous licence Creative-Commons