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 :

Gestion des char : pourquoi ça crash ?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Modérateur
    Avatar de kolodz
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2008
    Messages
    2 209
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 209
    Billets dans le blog
    52
    Par défaut Gestion des char : pourquoi ça crash ?
    Bonjour,

    Je viens de débugé une DLL écrite en C pour une application Java. Cette dll provoquait des crash (non systématique) de l'application Java lors de l'initialisation :
    #
    # An unexpected error has been detected by HotSpot Virtual Machine:
    #
    # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x7706e3be, pid=476, tid=4880
    #
    # Java VM: Java HotSpot(TM) Client VM (1.5.0_13-b05 mixed mode)
    # Problematic frame:
    # C [ntdll.dll+0x2e3be]
    #
    Après un peu de temps, la cause du crash s'est rapprochée des lignes suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char * sChemin = NULL;
    char nomIni[250]="\0"; 
    sChemin = sC_GEN_AddSepToDirectory(nomFichier);
    strcat(sChemin,"MONFICHIER.INI");
    En sachant que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FCT_EXP char * sC_GEN_AddSepToDirectory(char * _sChemin) {
    // L'implémentation de la méthode ...
    }
    En comparant avec le reste du code C à ma disposition dans cette DLL, j'ai mis le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char sChemin[250] = "\0";
    strcpy(sChemin,sC_GEN_AddSepToDirectory(nomFichier));
    printf(sChemin);
    strcat(sChemin,"MONFICHIER.INI");
    Après une série d'essai, je n'ai plus de crash de l'application avec la DLL corrigé.

    Ma question est pourquoi la DLL provoquait un crash ?

    Cordialement,
    Patrick Kolodziejczyk.
    Si une réponse vous a été utile pensez à
    Si vous avez eu la réponse à votre question, marquez votre discussion
    Pensez aux FAQs et aux tutoriels et cours.

  2. #2
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 315
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 315
    Billets dans le blog
    5
    Par défaut
    Bonjour.

    La fonction FCT_EXP char * sC_GEN_AddSepToDirectory(char * _sChemin) allouait-elle correctement l'espace nécessaire pour la chaîne retournée ?

  3. #3
    Modérateur
    Avatar de kolodz
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2008
    Messages
    2 209
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 209
    Billets dans le blog
    52
    Par défaut
    Que veux tu dire par "correctement " ?
    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
    FCT_EXP char * sC_GEN_AddSepToDirectory(char * _sChemin) 
    {
    	char * sChemin;
    	int taille = 0;
     
    	if(_sChemin == NULL) 	
    	{
    		_sChemin = malloc(sizeof(char));	 
    		_sChemin="\0";
    	}
     
    	sChemin = strrchr(  _sChemin, XGN_ANTISLASH); 
    	/* Il n'y a pas de sép à la fin du chemin donc on le met */
    	if(!sChemin || strlen(sChemin) > 1)
    	{
    		taille = strlen(_sChemin);
    		sChemin = malloc((taille+2)*sizeof(char));	 
    		strncpy(sChemin, _sChemin, taille);
    		sChemin[taille] = XGN_ANTISLASH;
    		sChemin[taille+1] = '\0';
    	}
    	/* Il y a un sép à la fin du chemin c'est bon */
    	else
    	{
    		sChemin =  _sChemin;
    	}
     
     	return sChemin;
     }
    J'ai bien le malloc pour la chaine de retour, mais je ne pense pas que c'est cela dont tu parle...

    Cordialement,
    Patrick Kolodziejczyk.
    Si une réponse vous a été utile pensez à
    Si vous avez eu la réponse à votre question, marquez votre discussion
    Pensez aux FAQs et aux tutoriels et cours.

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 487
    Par défaut
    Bonsoir,

    Citation Envoyé par kolodz Voir le message
    Que veux tu dire par "correctement " ?
    Il y a une énorme erreur dans le passage suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	if(_sChemin == NULL) 	
    	{
    		_sChemin = malloc(sizeof(char));	 
    		_sChemin="\0";
    	}
    Tu ne déposes pas un caractère nul dans l'espace fraîchement alloué mais tu détournes le pointeur pour le faire pointer une autre chaîne, en lecture seule. Ce faisant, tu perds la valeur de retour renvoyée par malloc() et tu provoques une fuite de mémoire.

    Par la suite, si ta condition est fausse, tu renvoies directement cette adresse à l'utilisateur qui, lui, pense qu'elle a été allouée. S'il essaie d'y écrire, cela plantera. S'il essaie de la libérer avec free(), cela plantera aussi.

  5. #5
    Modérateur
    Avatar de kolodz
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2008
    Messages
    2 209
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 209
    Billets dans le blog
    52
    Par défaut
    Je n'ai pas bien compris ton explication. Mais globalement, tout les appels à cette méthodes peuvent provoquer un crash.
    La modification que j'ai fait n'est donc qu'une rustine...

    Si je reprends ton explication :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _sChemin = malloc(sizeof(char));
    On réalisé une allocation mémoire et place un mon pointeur de char dans la variable.
    On place le pointeur du caractère null dans la variable.
    Ce qui fait qu'on perd la référence de ce qu'on vient d'alloué en mémoire. (Fuite mémoire de la taille d'un char)

    Cependant, pour cette partie :
    Par la suite, si ta condition est fausse, tu renvoies directement cette adresse à l'utilisateur qui, lui, pense qu'elle a été allouée.
    Si _sChemin a été initialé avec une caractère nul, alors sChemin sera forcément un pointeur nul. Car strrchr, il ne trouvera pas occurrence cherché.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sChemin = strrchr(  _sChemin, XGN_ANTISLASH);
    Ce qui fait que je passe dans ce morceau de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    taille = strlen(_sChemin);
    sChemin = malloc((taille+2)*sizeof(char));	 
    strncpy(sChemin, _sChemin, taille);
    sChemin[taille] = XGN_ANTISLASH;
    sChemin[taille+1] = '\0';
    Dans ce cas là, strlen(_sChemin) retournera 0.
    On aura donc sChemin ayant le contenu suivant {["\"],["\0"]} (ma synthase ressemble plus à du json que du c non ?)

    Par contre, si on donne un pointeur de char non null. qui finit par un XGN_ANTISLASH et qui est en plus en read only. Là ça va crashé, non ?

    Cordialement,
    Patrick Kolodziejczyk.
    Si une réponse vous a été utile pensez à
    Si vous avez eu la réponse à votre question, marquez votre discussion
    Pensez aux FAQs et aux tutoriels et cours.

  6. #6
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 315
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 315
    Billets dans le blog
    5
    Par défaut
    Je ferais plutôt :
    Enfin je crois...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 23/06/2006, 10h23
  2. [reseaux] Gestion des threads en perl
    Par totox17 dans le forum Programmation et administration système
    Réponses: 2
    Dernier message: 28/11/2002, 09h40
  3. Gestion des variables - mémoire ?
    Par RIVOLLET dans le forum Langage
    Réponses: 4
    Dernier message: 26/10/2002, 12h44
  4. Réponses: 4
    Dernier message: 04/07/2002, 12h31
  5. c: gestion des exceptions
    Par vince_lille dans le forum C
    Réponses: 7
    Dernier message: 05/06/2002, 14h11

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