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 :

Besoin d'aide "Segmentation fault"


Sujet :

C

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2020
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2020
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Besoin d'aide "Segmentation fault"
    Salut, j'essaie d'écrire une fonction dans le cadre d'un projet d'étude qui inverse les valeurs d'un tableau et retourne ce tableau. Seulement la console me renvoie "segmentation fault". j'ai donc essayé d'allouer la mémoire de ce pointeur mais sans effet. Si quelqu'un peut m'aider

    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
    char* IMPLEMENT(mkReverse)(char *str)
    {
    	int i,j;
    	int n;
    	int temp;
    	while(str[n] != '\0')
    	{
    		n = n+1;
    	}
    	str = malloc(n*sizeof(char));
    	for(j=n-1 ,i=0; j>i ; j--,i++)
    	{
    		temp = str[i];
    		str[i] = str[j];
    		str[j] = temp;
    	}
    	return(str);
    }

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    - C'est quoi l'idée de prendre un screenshot et l'uploader au lieu de copier/coller le texte ?
    - Que vaut n ?
    - strlen est interdit ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Rulio777 Voir le message
    j'ai donc essayé d'allouer la mémoire de ce pointeur mais sans effet.
    Ben si, un gros effet: tu perds la string d'origine !!!
    Tu reçois une string dans "str" et là, tu écris 3 lignes en dessous "ce qu'il y a dans str je m'en fiche, je lui mets autre chose" alors détrompe toi, cela a un effet du tonnerre.

    Citation Envoyé par Rulio777 Voir le message
    j'essaie d'écrire une fonction dans le cadre d'un projet d'étude qui inverse les valeurs d'un tableau et retourne ce tableau.
    Ben ton algo est bon. Aurait été bon si "str" n'avait pas été perdu entre temps.

    Citation Envoyé par Rulio777 Voir le message
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while(str[n] != '\0')
    	{
    		n = n+1;
    	}
    Tu peux me dire combien vaut "n" quand la boucle commence ????

    for (n=0; str[n] != '\0'; n++);.

    PS: ta fonction ne pourra pas fonctionner sur les chaines statiques (car invariantes). Autrement dit, impossible de lui passer une chaine en dur style "toto". Tu ne pourras que lui passer un tableau de char.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre averti
    Homme Profil pro
    très occupé
    Inscrit en
    Juillet 2014
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : très occupé

    Informations forums :
    Inscription : Juillet 2014
    Messages : 137
    Points : 411
    Points
    411
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    PS: ta fonction ne pourra pas fonctionner sur les chaines statiques (car invariantes). Autrement dit, impossible de lui passer une chaine en dur style "toto". Tu ne pourras que lui passer un tableau de char.
    Pour cette raison, je serais moins optimiste sur l'algorithme, qui ne semblerait bon que pour un traitement de la chaîne fournie sur place (donc avec un tableau passé en paramètre).

    Si la fonction à vocation à pouvoir traiter n'importe quelle chaîne, alors il semble nécessaire qu'une fonction avec un prototype du genre char * reverse(char * str) renvoie avec le return un pointeur vers une nouvelle chaîne, allouée avec malloc() par la fonction.

    Dans ce cas, l'algorithme de traitement de la chaîne sur place n'est plus utile. On fera bien plus simple en copiant les chars de la chaîne passée en paramètre dans la nouvelle en partant de la fin.

    La fonction appelante aura la responsabilité de libérer la mémoire allouée par cette fonction. Cela devrait être documenté.

    On peut aussi faire deux fonctions :
    • une void reverse_null_terminated_char_array(char * str) qui peut fonctionner sur place et n'a pas à retourner quoi que ce soit
    • une char * get_any_C_string_reversed(char * str) qui traite toute chaîne C et renvoie une nouvelle chaîne allouée


    @Rulio777 : c'est quoi "IMPLEMENT(mkReverse)" ... une macro ? Par curiosité, peux-tu nous dire ce qu'elle fait ?

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par -Eks- Voir le message
    Pour cette raison, je serais moins optimiste sur l'algorithme, qui ne semblerait bon que pour un traitement de la chaîne fournie sur place (donc avec un tableau passé en paramètre).

    Si la fonction à vocation à pouvoir traiter n'importe quelle chaîne, alors il semble nécessaire qu'une fonction avec un prototype du genre char * reverse(char * str) renvoie avec le return un pointeur vers une nouvelle chaîne, allouée avec malloc() par la fonction.
    Exact (tout comme le fait strdup()). Mais je suis parti de l'hypothèse qu'il était très débutant (il n'utilise pas de pointeur pour compter la longueur, et sa déclaration de fonction semble assez fantaisiste), lequel n'est pas encore familiarisé avec ces notions de pointeur et de malloc. Sinon effectivement je suis bien d'accord. Pour une fonction universelle qui pourra manger des trucs comme "toto" qu'elle ne pourra pas modifier fatalement il faudra créer une nouvelle string à la volée
    Tout dépend en fait du contexte de ce topic (devoir? exo? TP? ops?)

    Citation Envoyé par -Eks- Voir le message
    Dans ce cas, l'algorithme de traitement de la chaîne sur place n'est plus utile.
    Ben en fait, ça sera carrément interdit, la chaine reçue étant présumée const.

    Citation Envoyé par -Eks- Voir le message
    La fonction appelante aura la responsabilité de libérer la mémoire allouée par cette fonction. Cela devrait être documenté.
    Ce ne sera pas une nouveauté. Des tas de fonctions sont comme ça (strdup(), getline(), ...).

    Citation Envoyé par -Eks- Voir le message
    @Rulio777 : c'est quoi "IMPLEMENT(mkReverse)" ... une macro ? Par curiosité, peux-tu nous dire ce qu'elle fait ?
    Quand j'ai tapé ça (j'avais pas pensé à une macro), le compilo l'a traduit par un pointeur de fonction mal foutu...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 324
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 324
    Points : 4 134
    Points
    4 134
    Par défaut Code initial presque bon ?
    Bonjour,

    Tel qu'écrit, même avec les modifications proposées, il reste le problème de n qui est l'indice le plus élevé mais pas le nombre d'éléments (1 de plus).

    Par ailleurs, la permutation oublie de remettre un caractère nul en position n. Il n'est alors pas pas étonnant qu'au premier usage de la chaine retournée ça fasse

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Guesset Voir le message
    Par ailleurs, la permutation oublie de remettre un caractère nul en position n. Il n'est alors pas pas étonnant qu'au premier usage de la chaine retournée ça fasse
    Pas besoin et non, tel qu'il est écrit l'algo fonctionne ("j" commence à "n-1"). La chaine "abcd" (ou plus précisément {'a', 'b', 'c', 'd', '\0'}) devient donc "dcba" et le '\0' n'a pas bougé.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    D'un certain côté, ça dépend un peu si on privilégie la compréhension, avec l'idée de faire ça "étape par étape", ou la performance.
    Point de vue compréhension, on peut apprécier l'idée de faire l'inversion "sur place":
    Code C : 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
    size_t strlen_pour_epitarques(char const *str)
    {
    	size_t n = 0;
    	while(str[n]!='\0')
    		n++;
    	return n;
    }
     
    char* inPlaceReverse2(char *str, size_t length)
    {
    	size_t i;
    	for(i=0 ; i<length/2 ; i++)
    	{
    		char tmp = str[length-1-i];
    		str[length-1-i] = str[i];
    		str[i] = tmp;
    	}
    	return str;
    }
    char* inPlaceReverse(char *str)
    {
    	return inPlaceReverse2(str, strlen_pour_epitarques(str));
    }
    Ou de faire une copie puis une inversion "sur place":
    Code C : 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
    char* strdup(char const *src)
    {
    	size_t length = strlen_pour_epitarques(src);
    	char* ret = malloc(length+1);
    	if(ret != NULL)
    	{
    		size_t i;
    		for(i=0 ; i <= length ; i++) //Ici on va de 0 à length INCLUS pour copier le \0
    			ret[i] = src[i];
    	}
    	return ret;
    }
     
    char* reverseA(char const *str)
    {
    	char* ret = strdup(str);
    	if(ret != NULL)
    		inPlaceReverse(ret);
    	return ret;
    }

    Par contre, si on veut de la performance, on préférera mesurer la longueur une seule fois, et faire l'inversion dès la copie:
    Code C : 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
    void reverse_memcpy(void* dstV, void const* srcV, size_t size)
    {
    	char * dst = dstV;
    	char const* src = srcV;
    	size_t i;
    	for(i=0 ; i<size ; i++)
    	{
    		dst[i] = src[size-1-i];
    	}
    }
     
    char* reverseB(char const *str)
    {
    	size_t length = strlen_pour_epitarques(str);
    	char* ret = malloc(length+1);
    	if(ret != NULL)
    	{
    		reverse_memcpy(ret, str, length);
    		ret[length]='\0';
    	}
    	return ret;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 324
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 324
    Points : 4 134
    Points
    4 134
    Par défaut Inversion renversante
    Bonjour Sve,

    Citation Envoyé par Sve@r Voir le message
    Pas besoin et non, tel qu'il est écrit l'algo fonctionne ("j" commence à "n-1"). La chaine "abcd" (ou plus précisément {'a', 'b', 'c', 'd', '\0'}) devient donc "dcba" et le '\0' n'a pas bougé.
    Si le /0 est en n il y a donc, de 0 à n, n+1 caractères.
    Or le malloc n'en affecte que n soit de 0 à n-1.
    Je ne vois pas où il pourrait mettre le \0 terminal.

    Ceci étant je ne vois pas à quoi sert le malloc (qui de plus va écraser l'accès au contenu du str d'origine) si c'est pour faire une inversion in situ.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  10. #10
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Guesset Voir le message
    Ceci étant je ne vois pas à quoi sert le malloc (qui de plus va écraser l'accès au contenu du str d'origine) si c'est pour faire une inversion in situ.
    Hé oui, sans ce malloc (auquel je n'avais plus fait attention), son algo fonctionne puisqu'il permute une str in situ donc ayant déjà le '\0' de positionné (et qui n'est alors pas perdue)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. aide sur ce le probleme de segmentation fault
    Par selmani300 dans le forum C++
    Réponses: 3
    Dernier message: 26/03/2009, 07h48
  2. Aide pour résoudre un Segmentation fault
    Par Premium dans le forum C
    Réponses: 8
    Dernier message: 10/12/2005, 12h26

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