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 :

Probléme de pointeur avec des pointeurs de char *


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Profil pro
    fzefe
    Inscrit en
    Juin 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : Gabon

    Informations professionnelles :
    Activité : fzefe

    Informations forums :
    Inscription : Juin 2009
    Messages : 18
    Par défaut Probléme de pointeur avec des pointeurs de char *
    Hello,

    Je suis entrain de développer un petit logiciel pour afficher en lettre un nombre que l'on aurait rentré en paramétre. J'ai donc fait mon algo mais je rencontre un bon gros segfault que je ne sais pas résoudre.

    Je vous présente le projet

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
     
    int conversionNombre(int nombreFinal)
    {
    	char *myNumber = toArray(nombreFinal);
    	char *motFinal = " ";
    	int i = 0;
    	if (myNumber[i] == '-')
    		myNumber = decalage(myNumber);
    	if (my_strlen(myNumber) == 1)
    	{
    		if (nombreFinal < 0)
    			decalageChiffre(&motFinal, "Moins ");
    		decalageChiffre(&motFinal, chiffres[(int)myNumber[0] - 48]);
    		my_putstr(motFinal);
    		my_putchar('\n');
    		return 0;
    	}
    	myNumber = reverseNb(myNumber);
    	while (myNumber[i] != '\0')
    	{
    		if (findChiffreOrNumber(i) == 1)
    			traitementNombre(&motFinal, myNumber[i], myNumber[i - 1], i);
    		else
    			traitementChiffre(&motFinal, myNumber[i], myNumber[i + 1], i);
    		i++;
    	}
    	if (nombreFinal < 0)
    		decalageNb(&motFinal, "Moins ");
    	my_putstr(motFinal);
    	my_putchar('\n');
    	motFinal = " ";
    	return 0;
    }
     
    void traitementChiffre(char **motFinal, char current, char previous, int indice)
    {
    	char *temp = " ";
    	if (indice == 0)
    	{
    		if (previous != '1' && previous != '7' && previous != '9' && current != '0')
    		{
    			decalageChiffre(motFinal, chiffres[(int)current - 48]);
    		}
    	}
    	else
    	{
    		if (current != '0')
    		{
    			if (current != '1')
    				decalageChiffre(&temp, chiffres[(int)current - 48]);
    			decalageChiffre(&temp, unite[indice - 2]);
    			decalageNb(motFinal, temp);
    		}
    	}
    }
     
    void traitementNombre(char **motFinal, char current, char next, int indice)
    {
    	if (current != '1' && current != '0')
    	{
    		if (next == '1')
    			decalageNb(motFinal, " et ");
    		decalageNb(motFinal, nb[(int)current - 50]);
    	}
    	if ((current == '1' || current == '7' || current == '9') && current != '0')
    	{
    		if (next == '1' && current != '1')
    			decalageNb(motFinal, " et ");
    		decalageChiffre(motFinal, nbDizaine[(int)next - 48]);
    	}
    }
     
    void decalageChiffre (char **string, char *toAdd)
    {
    	int i = 0;
    	int j = 0;
    	int size = my_strlen(*string);
    	int sizeAdd = my_strlen(toAdd);
    	char * temp = calloc((size + sizeAdd - 2), sizeof(char));
    	if (size > 1)
    	{
    		while (i < size)
    		{
    			temp[j] = *string[i];
    			j++;
    			i++;
    		}
    	}
    	i = 0;
    	while (toAdd[i] != '\0')
    	{
    		temp[j] = toAdd[i];
    		j++;
    		i++;
    	}
    	//string = realloc(string, my_strlen(temp) + 1 * sizeof(char));
    	*string = temp;
    	free(temp);
    }
     
    void decalageNb (char **string, char *toAdd)
    {
    	int i = 0;
    	int j = 0;
    	int size = my_strlen(*string);
    	int sizeAdd = my_strlen(toAdd);
    	char * temp = calloc((size + sizeAdd - 2), sizeof(char));
    	while (toAdd[i] != '\0')
    	{
    		temp[j] = toAdd[i];
    		j++;
    		i++;
    	}
    	i = 0;
    	if (size > 1)
    	{
    		while (i < size)
    		{
    			temp[j] = *string[i];
    			j++;
    			i++;
    		}
    	}
    	//string = realloc(string, my_strlen(temp) + 1 * sizeof(char));
    	*string = temp;
    	free(temp);
    }
    Le principal soucis que je rencontre est que l'adresse mémoire change lorsque l'on passe en paramétre le pointeur de motFinal depuis conversionNombre vers traitementChiffre.

    Ce qui fait que lorsque je veux concaténer la chaîne dans "decalageChiffre" je ne retrouve pas ma chaîne.

    J'espére que ce que je demande n'est pas trop compliqué et surtout que mon code et mon explication sont assez claire.

    Merci d'avance

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Si tu remplaces char *temp = " "; par char temp[1024] = " ";, il se passe quoi ?

    je rencontre un bon gros segfault
    Quand ça se passe, il faut être capable de trouver la ligne exacte où cela se produit. 3 solutions : des printf() (pas trop bonne idée), un débogueur en pas à pas (bonne idée), un débogueur mémoire tel Valgrind (à vérifier mais devrait donner des indications intéressantes).

  3. #3
    Membre Expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Par défaut
    Valgrind indiquera en effet l'instruction qui envoie le segfault.
    Donc après il suffit de voir quelle variable "pourrait" segfaulter.

    (et vérifier si ça n'est pas un "bus error" qui proviendrait de l'erreur que Bktero montre)
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  4. #4
    Membre chevronné
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Par défaut
    Citation Envoyé par Bktero Voir le message
    un débogueur mémoire tel Valgrind (à vérifier mais devrait donner des indications intéressantes).
    Valgrind n’est pas du tout un « débogueur mémoire » (ce fût le cas à sa création, mais ce n’est plus vrai maintenant).
    Valgrind est un framework pour le développement d’outils d’analyse dynamique (par instrumentation binaire en l’occurrence).
    À la limite, un des outils de Valgrind (memcheck), peut être considéré comme un « débogueur mémoire ».

    Mais quitte à utiliser un outil de ce genre, si le PO à un compilateur récent (clang >= 3.3 ou gcc >= 4.8), autant passer par les versions intégrés de AddressSanitizer.
    L’overhead est grandement réduit (x2 contre x20 pour le ralentissement), bien que sur un programme comme celui-là, memcheck devrait être suffisamment rapide.

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Bktero souligne l'utilisation erronnée des constructions comme char *temp = " ";. Ce genre de choses réserve 2 bytes, initialisés par le blanc et le '\0', et met l'adresse du premier dans temp. Cette chaine de 2 bytes est NON MODIFIABLE (en contenu comme en longueur). Toute tentative pour la modifier peut aboutir à un plantage.

    Dans la fonction decalageNb(), cette construction n'a pas été utilisée et on a une allocation dynamique. Malheureusement, le code se termine mal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void decalageNb (char **string, char *toAdd)
    {
    ...
    	char * temp = calloc((size + sizeAdd - 2), sizeof(char));
    ...
    	*string = temp;
    	free(temp);
    }
    ce qui revient à renvoyer l'adresse d'une zone mémoire (temp) qui sera détruite la ligne suivante. Cette information est donc inutilisable par le programme appelant cette fonction. Si il l'utilise, on a un plantage dans le meilleur des cas et sinon un comportement indéfini, aléatoire,...

Discussions similaires

  1. Réponses: 7
    Dernier message: 29/03/2015, 12h55
  2. problème de fonction avec des pointeurs
    Par bl4cksky dans le forum Débuter
    Réponses: 16
    Dernier message: 09/09/2013, 12h28
  3. Soucis avec des pointeurs, des tableaux, des char*
    Par isabell3 dans le forum Débuter
    Réponses: 2
    Dernier message: 07/12/2009, 12h00
  4. Problème avec des pointeurs
    Par Darick dans le forum C
    Réponses: 4
    Dernier message: 15/05/2008, 09h43
  5. problème char-actéristique avec des pointeurs
    Par Antigonos Ier Gonatas dans le forum C
    Réponses: 11
    Dernier message: 16/04/2007, 21h22

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