Problème inexpliqué...

Résolu
LAngelus91 Messages postés 12 Date d'inscription lundi 8 novembre 2010 Statut Membre Dernière intervention 11 avril 2013 - 10 avril 2013 à 20:38
LAngelus91 Messages postés 12 Date d'inscription lundi 8 novembre 2010 Statut Membre Dernière intervention 11 avril 2013 - 11 avril 2013 à 18:07
Bonjour à tous!

Alors voilà mon problème :
j'ai deux fonctions,
-l'une retournant l'indice de la première occurrence d'un caractère dans une chaine,
-l'autre renvoyant l'indice de la dernière occurrence d'un caractère dans une chaine...

Les voilà

//Fonction permettant de recuperer l'indice de la première occurence d'un caractére dans une chaîne
int strwisfc(const char* chain, const char c){
int i;
for(i=0; i<strlen(chain);i++){
if (chain[i]==c)
return i;
}
return -1;
}

//Fonction permettant de recuperer l'indice de la dernière occurence d'un caractére dans une chaîne
int strwislc(const char* chain, const char c){
int i;
for(i=strlen(chain)-1; i>=0;i--){
if (chain[i]==c)
return i;
}
return -1;
}


Mon souci se trouve dans l'utilisation :

-Ca ça fonctionne très bien :
int lastOccurence = strwislc(test,'z');
int firstOccurence = strwisfc(test, 'z');
printf ("%d ?= %d\n", firstOccurence ,lastOccurence );




-Ca ça me plante tout à l’exécution :
printf ("%d ?= %d\n", strwisfc(test, 'z'),strwislc(test,'z'));


Info :
Je code en c ansi avec eclipse.

C'est pas super handicapant mais si quelqu'un pouvait m'expliquer la raison de ce plantage, je lui en serait reconnaissant!

Merci d'avance!

11 réponses

LAngelus91 Messages postés 12 Date d'inscription lundi 8 novembre 2010 Statut Membre Dernière intervention 11 avril 2013
11 avril 2013 à 18:07
Bon j'ai trouvé la solution, une illumination... je suis un boulet j'ai oublié les conditions de sécurité des fonctions:

if (chain==NULL)
  return -1;


Je m'auto-flagelle pour l'occaz...

Merci quand même pour l'aide!
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 26
10 avril 2013 à 21:01
Salut,

je sais pas vraiment ce qui plante pour toi, mais le CRT fourni 2 fonctions pour faire ça : strchr et strrchr

char string[] = "test z ....";
const int _z = 'z';
int resultForward, resultReverse;

char *pdest = strchr( string, _z );
resultForward = (int)(pdest - string + 1);

pdest = strrchr( string, _z );
resultReverse = (int)(pdest - string + 1);


bye...
LAngelus91 Messages postés 12 Date d'inscription lundi 8 novembre 2010 Statut Membre Dernière intervention 11 avril 2013
10 avril 2013 à 21:08
Je sais bien, mais je ne doit utiliser que les bibliothèques standards (et de manière limitée):(

Merci quand même!
cptpingu Messages postés 3839 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 29 juin 2024 124
10 avril 2013 à 22:11
Bonjour.

Je ne vois pas où est l'erreur. Il y a bien quelques warnings (problème de comparaison entre signé et non signé), mais même en corrigeant je n'ai aucun souci.
J'ai utilisé ce code:
#include <stdio.h>
#include <string.h>

int strwisfc(const char* chain, const char c)
{
  unsigned int i = 0;
  for (i = 0; i < strlen(chain); i++)
    if (chain[i] == c)
      return i;

  return -1;
}

int strwislc(const char* chain, const char c)
{
  int i = 0;
  for (i = strlen(chain) - 1; i >= 0; i--)
    if (chain[i] == c)
      return i;

  return -1;
}

int main(void)
{
  const char* test1 = "ztotoz";
  const char* test2 = "not found";

  printf ("%d ?= %d\n", strwisfc(test1, 'z'), strwislc(test1, 'z'));
  printf ("%d ?= %d\n", strwisfc(test2, 'z'), strwislc(test2, 'z'));

  return 0;
}


Peux-tu poster ton code ? Peux-tu passer ton code dans un debugger et regarder la ligne qui fait planter ?

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question

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

Posez votre question
LAngelus91 Messages postés 12 Date d'inscription lundi 8 novembre 2010 Statut Membre Dernière intervention 11 avril 2013
10 avril 2013 à 22:51
Merci pour la réponse. Pour ma part j'ai pas eu de Warnings même en -Wall et j'avoue que je n'arrive pas à configurer correctement GDB. Je ne vois pas quelles infos supplémentaires je peut donner. Surtout que rien ne s'affiche (c'est une erreur style : ****.exe à cessé de fonctionner).

Je ne peut pas non plus poster l’intégralité de mon code, à la limite juste celui avec les fonctions qui plantent. Mais pour le reste je ne peut malheureusement pas (et de toute façon j'ai bien isolé toutes les parties du code une par une et c'est la seule qui me faisait planter).
LAngelus91 Messages postés 12 Date d'inscription lundi 8 novembre 2010 Statut Membre Dernière intervention 11 avril 2013
10 avril 2013 à 23:09
Finalement j'ai lancé GDB directement en commande et il me sort un "Segmentation fault".
cptpingu Messages postés 3839 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 29 juin 2024 124
10 avril 2013 à 23:18
j'ai pas eu de Warnings même en -Wall

Pourtant il y avait bien un warning. Dans ta fonction "strwisfc" dans la boucle for tu comparais un "unsigned" (type de retour du strlen) avec un "signed" (le "int i").
J'ai utilisé la commande suivante: gcc -W -Wall -ansi -pedantic <liste fichier>
J'ai un gcc 4.5.2 (la version la plus récente est 4.7). Tu peux voir la version via "gcc --version".

j'avoue que je n'arrive pas à configurer correctement GDB

Il n'y a rien à configurer. Lance simplement gdb (gdb ./nom_du_binaire puis "r"). Ensuite une fois que ça plante, tu regardes l'état de la backtrace (commande "bt" en mode console). Si tu parles de la configuration de gdb dans eclipse, alors je ne sais pas (j'utilise gdb en mode console).

j'ai bien isolé toutes les parties du code une par une et c'est la seule qui me faisait planter

L'erreur est surement ailleurs. Sache que l'erreur peut être là où tu ne penses pas (j'ai quelques exemples en tête: problème de synchro multithreading, strlen sur une chaine non unicode qui biaise le résultat, etc...). C'est la raison pour laquelle j'ai besoin de plus d'information.
Si tu peux monter un mini exemple qui plante (il te faut créer un nouveau binaire, en extrayant les morceaux de code que tu ne veux pas (ou ne peux pas) montrer).
Je ne peux malheureusement pas t'aider plus sans avoir plus de code :(

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
cptpingu Messages postés 3839 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 29 juin 2024 124
10 avril 2013 à 23:19
Finalement j'ai lancé GDB directement en commande et il me sort un "Segmentation fault".

Que donne un "bt" ? (Toujours en console, juste après le plantage ?).
Attention de bien compiler avec l'option -g (mode debug) sinon tu ne verras pas grand chose :)

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
LAngelus91 Messages postés 12 Date d'inscription lundi 8 novembre 2010 Statut Membre Dernière intervention 11 avril 2013
10 avril 2013 à 23:21
Et ici, la portion de code qui me pose problème :

		while (strwisfs(ln, endingChar)!=0){
line = (int)ftell(file);
ln = fgetln(file);
printf("Line : '%s'\n", ln);
if (strwisfc(ln, '\\')!=-1){
endLbl = line + strwisfc(ln, ' ');
addBloc(line, &newBloc);
newBloc->labelEnd = endLbl-1;
newBloc->commentStart = endLbl + 1;
if (strwislc(ln, '\\') == strwisfc(ln, '\\')) { //Plantage ici <------
#if 0
if (strcmp(chain->chain,"///")==0){
newBloc->commentEnd = (int)ftell(file);
} else if(strcmp(chain->chain,"/**")==0) {
newBloc->commentEnd = strwislc(ln, '\\')-2;
} else {
for (ln = fgetln(file);strwisfc(ln, '\\')!=-1 || strwisfs(ln, "*/")!=-1;ln = fgetln(file));
newBloc->commentEnd = (int)ftell(file) + strwisfc(ln, '\\') - 1;
}
#endif
} else {
fprintf(stderr, "Error : two comments in-lined, feedBlocks() can't manage!");
}
}
}
LAngelus91 Messages postés 12 Date d'inscription lundi 8 novembre 2010 Statut Membre Dernière intervention 11 avril 2013
10 avril 2013 à 23:30
(gdb) bt
#0  0x00401c49 in ?? ()
#1  0x00401861 in ?? ()
#2  0x00401953 in ?? ()
#3  0x00401468 in ?? ()
#4  0x004010b9 in ?? ()
#5  0x00401284 in ?? ()
#6  0x750d33aa in KERNEL32!BaseCleanupAppcompatCacheSupport ()
   from C:\Windows\syswow64\kernel32.dll
#7  0x0028ffd4 in ?? ()
#8  0x77639ef2 in ntdll!RtlpNtSetValueKey ()
   from C:\Windows\system32\ntdll.dll
#9  0x7efde000 in ?? ()
#10 0x77639ec5 in ntdll!RtlpNtSetValueKey ()
   from C:\Windows\system32\ntdll.dll
#11 0x0040126c in ?? ()
#12 0x00000000 in ?? ()
cptpingu Messages postés 3839 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 29 juin 2024 124
11 avril 2013 à 10:39
Le code donné, n'étant pas autonome et incomplet, il m'est impossible de voir ce qui ne va pas (je n'ai pas l'état des variables à chaque instant). Au niveau du code, plutôt que de refaire des "strwisfc(ln, '\\'))" tu devrais l'appeler une seule fois, le stocker et ensuite vérifier la variable. Ça t'économisera quelques appels de fonctions inutiles.

Pour la trace "bt", tu n'as pas du compiler avec "-g", ce qui fait que l'on ne voit rien.

Encore, une fois, prépare moi un exemple autonome, compilable, qui met en avant le plantage et je pourrais le regarder. Je ne peux malheureusement rien faire de plus, sans ça.

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Rejoignez-nous