Un pointeur qui disparait !

benjiiim94 Messages postés 96 Date d'inscription vendredi 17 décembre 2004 Statut Membre Dernière intervention 13 juillet 2007 - 22 mars 2005 à 17:56
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011 - 23 mars 2005 à 03:51
Bonjour,



J'ai un gros problème avec un pointeur !

Je devellope une fonction qui recherche un mot dans un texte afin de
stocker l'indice de début et de celui-ci. Pour ce stockage j'utilise un
pointeur a deux dimensions. Malheuresement, j'ai l'impression que ce
pointeur s'efface une fois que je sors de la fonction !

Si vous pouviez regarder mon code s'il vous plait...



Merci beaucoup



#include <stdlib.h>

#include <stdio.h>

#include <string.h>



int rechercher(int **selection,char *tab, int cpt_selection, char *mot, int mode,int *cpt)

{



int cpt2;

int tai_mot=strlen(mot);



while (tab[*cpt]!=0)

{



cpt2 = 0;



if (tab[*cpt]==mot[cpt2])

{



while ((tab[*cpt]==mot[cpt2])&&(cpt2<=tai_mot))

{

(*cpt)++;

cpt2++;

}



if
(cpt2==tai_mot) //on a trouvé un mot. On sauvegarde donc l'indice du
début et de fin de ce mot dans le tableau de selection

{






selection=(int **) realloc(selection , (cpt_selection+1) * sizeof(int
*));//on alloue le nombre de ligne nécessaire




*(selection+cpt_selection)=(int *) malloc(2 * sizeof(int)); //on alloue
les deux cases




selection[cpt_selection][0]=*cpt-tai_mot;

selection[cpt_selection][1]=*cpt-1;

cpt_selection++;



}



}else

{

(*cpt)++;

}



}



printf("\ndebut : %ld\n",selection[0][0]);

printf("fin : %ld\n",selection[0][1]);



return cpt_selection;

}





int main()

{

char tab[300]={"C'est un point important ! point point "};

char mot[10]={"point"};

int **selection;

int tai_util=strlen(tab);

int cpt_selection=0, mode=0, cpt=0;



selection=(int **) malloc(1 * sizeof(int *)); //on alloue de l'espace pour le tableau de selection



puts(tab);

printf("\n\n");





printf("2 : rechercher tout");

fflush(stdin);

scanf("%ld",&mode);



if (mode==2) cpt_selection=rechercher(selection,tab,cpt_selection,mot,mode,&cpt);



printf("\ncpt selection : %ld\n",cpt_selection);

printf("debut après : %ld\n",selection[0][0]);

printf("fin après : %ld\n",selection[0][1]);





system("PAUSE");

return 0;

}

7 réponses

NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
22 mars 2005 à 19:44
Exemple, tu vas tout comprendre(enfin, ca devrait :})

void func1( int i )
{
i = 5;
}
int main()
{
int i = 7;
func1( i );

printf("%d\n", i); /* ca va afficher: 7 */

/*
pourquoi? parce seul la valeur
de `i` est envoyée à la fonction func1()
il faudrait plutôt lui envoyer son adresse(celle de `i`)
*/

return 0;
}

void func2( int * i )
{
(*i) = 5; /* il faut le déréférencer */
/*
(*i) == int i; du main()
ta un accès direct à la variable(via son adresse)
*/
}
int main()
{
int i = 7;
func2( &i ); /* on envoi l'adresse de `i` */

printf("%d\n", i); /* ca va afficher: 5 */

return 0;
}

avec ton code:

void ta_fonction( int *** selection, ... )
{

int ** ptr;

/* code ... */

ptr = (int **) realloc( (*selection), nouvelle_taille ); /* même chose ici, il faut déréférencer */
if ( NULL != ptr )
{
(*selection) = ptr;
}
else
{
!!!!ERROR!!!!
}

/* code ... */
}
int main()
{

int ** selection;
ta_fonction( &selection, ... ); /* on envoi l'adresse de `selection` */

/* ... */

return 0;

}

Voilà, j'espère que ce n'est pas trop vague comme explication :}

~(.:: NitRic ::.)~
0
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
22 mars 2005 à 19:54
Au fait:

pointeur = realloc( pointeur, nouvelle_taille );

c'est mauvais ca, très mauvais, si realloc() échoue
tu pers tout. exemple:

char * string;
string = malloc( 256 );

strcpy( string, une_chaine_ici );
string = realloc( string, 512 );

Si realloc() échoue, string vaut NULL par la suite et donc
la mémoire allouée via malloc() est perdu => fuite de mémoire

donc, un pointeur supplémentaire est, et de loin, préférable.

char * string;
char * pointer;

string = malloc( 256 );

strcpy( string, une_chaine_ici );
pointer = realloc( string, 512 );

if ( NULL != pointer )
string = pointer;
else
puts("ERROR!!!");

Si realloc() échoue, `pointer` vaut NULL mais `string` reste inchangé donc
tu as toujours ton pointeur sur la mémoire allouée

Au fait, pour ce qui est de l'accès aux différents éléments de ton tableau `selection` dans
ta fonction, c'est simple:

void ta_fonction( int *** selection, ... )
{

/* code, allocation, code, ... */
(*selection)[x][y] = valeur;

/* etc ... */

}

~(.:: NitRic ::.)~
0
benjiiim94 Messages postés 96 Date d'inscription vendredi 17 décembre 2004 Statut Membre Dernière intervention 13 juillet 2007
22 mars 2005 à 21:13
Oki pour le realloc, je securiserai ca plus tard.



En ce qui concerne le passage du pointeur, si je peus me permettre tu as tort....

En effet, je vai pas t'aprendre que le pointeur est une adresse, donc en metant **selection, ca passe.

Le problème n'est malheuresement pas ici. Je viens juste de
m'apercevoir qu'il fonctionne très bien avec le mode pas a pas de Dev
C++ ! C'est a ne rien n'y comprendre !



Merci de votre aide
0
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
23 mars 2005 à 03:34
Fait un test tout bête:

void fonction( int ** tableau )
{
tableau = (int **) malloc( 5 * sizeof(int *) );
(*tableau) = malloc( 5 * sizeof(int) );


(*tableau)[0] = 5;
(*tableau)[1] = 17;
}
int main()
{
int ** tableau;


fonction( tableau );
printf("%d - %d\n", (*tableau)[0], (*tableau)[1]);

free( *tableau );
free( tableau );

return 0;
}

Si tu as de la chance, ca va afficher du garbage, dans le cas contraire, ca va planter!
Ta fonction doit accepter un `int *** selection` et tu dois lui passer `&selection`

La variable elle-même représente une adresse, pour pouvoir modifier directement `selection`, tu dois donner aux fonctions l'adresse de cette dernière. Le code, version fonctionnel, serait:

void fonction( int *** tableau )
{
(*tableau) = (int **) malloc( 5 * sizeof(int *) );
*(*tableau) = malloc( 5 * sizeof(int) );


*(*tableau)[0] = 5;
*(*tableau)[1] = 17;

/*********************************************
*
*tableau pointe sur `selection` (dans le main())
*(*tableau) pointe sur `*selection` ou si tu préfère, sur `selection[0]`
*(*tableau)[0] pointe sur `(*selection)[0]` ou encore: `selection[0][0]`

Toi, dans ton code, lorsque tu `tente` de déréférencer `selection`
tu pointe sur: selection[0][0]

type func( int ** selection, ... )
{
/* code ... */
*(selection+cpt_selection)=(int *) malloc( ... );
/* code ... */
}

Dans ce code, tu pointe tout simplement sur `selection[0][cpt_selection]`

Va relire un peu sur les pointeurs, déréférencements, allocations mémoires,
etc ... etc ...

Dis toi que les variables que tes fonctions recoivent sont
locals aux fonctions alors, pour pouvoir modifier une variable
externe à la fonction(reçu en paramètre), la fonction doit
connaître l'adresse de la variable à modifier => son adresse !!!
Alors donne lui l'adresse de la variable à modifier!

Si ca peu t'aider, regarde ceci:

int ** selection;
&selection == adresse de base(de la variable)
* == pointeur qui pointe sur rien au début
* == autre pointeur qui pointe aussi sur rien

en gros, ca donne ceci:
& => * => adresse de `selection`
* => *
* => *
Voilà d'ou provient les trois astérix
*
*********************************************/

}
int main()
{
int ** tableau;


fonction( &tableau );
printf("%d - %d\n", (*tableau)[0], (*tableau)[1]);

free( *tableau );
free( tableau );

return 0;
}

Désolé si mes explications ne sont pas parfaites, j'avous ne pas être très doué dans ce domaine.

~(.:: NitRic ::.)~
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
23 mars 2005 à 03:39
En parlant du mode pas-a-pas, c'est normal, comme j'ai dis plus haut, variable => local
alors c'est tout à fait normal que les allocations mémoire/manipulations/etc... n'échoue pas, le contraire ne serait pas normal par contre.

~(.:: NitRic ::.)~
0
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
23 mars 2005 à 03:46
Dernière petite chose, si dans ta fonction tu voudrais éviter les: *(*(selection))[x] etc ... avoir quelque chose de plus ... `jolie/simple/...!?`, tu peux très bien faire par exemple:

type func( int *** selection, ... )
{

int ** ptr = NULL;
int ** sel = (*selection);

/* ... */
ptr = (int **) realloc( sel, ... );
/* ... */
sel[0] = (int *) malloc( ... );
/* ... */

(*selection) = sel; /* à ne pas oublier */
return value;
}

~(.:: NitRic ::.)~
0
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
23 mars 2005 à 03:51
0
Rejoignez-nous