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 :

segfault sur un cas basique ?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 14
    Par défaut segfault sur un cas basique ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int main(int argc, char *argv[])
    {
    char *p="Hello", a[]="Zello";
    
    a[0]='H';
    *(p+0)='Z';
    
    return(0);
    }
    Ok, ça m'a l'air basique et le retourner dans les sens, j'ai une erreur de segmentation sur l'instruction en rouge

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 119
    Par défaut
    Salut,
    c'est normal, tu ne peux pas modifier "Hello" (le comportement est non défini).

    Citation Envoyé par N1256
    6.4.5 String literals
    Syntax
    string-literal:
    " s-char-sequenceopt "

    If the program attempts to modify such an array, the behavior is undefined.
    p est un pointeur vers une chaine de caractères (un string literal ici), alors que a est un tableau de caractères que tu initialises avec "Hello".
    Tu peux modifier le contenu de a, mais pas la chaine pointé par p.

  3. #3
    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
    Pour compléter ce que vient de dire gulain, il faut savoir que quand tu fais ça :
    char *p="Hello", aucun espace mémoire n'est réservé sur le tas comme ce serait le cas avec malloc, ou sur la pile comme ce serait le cas avec le tableau a. La chaine "Hello" est mise dans une zone spécifique de la mémoire où sont placées les constantes. Tu ne peux donc pas modifier les données pointées par p, bien que tu puisses modifier p lui-même.

    Mon échange avec gangsoleil dans cette discussion pourra t'intéresser : http://www.developpez.net/forums/d12...n/#post6770934

    PS : char *p="Hello" est une allocation statique : http://fr.wikipedia.org/wiki/Allocation_de_m%C3%A9moire

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 14
    Par défaut
    Merci Messieurs pour ces réponses qui sont fondées.
    Je sentais bien l'effet "Constante"

    Aussi, je dois revoir un aspect d'un plus gros programme dans lequel un tableau de pointeurs de char est initialisé avec des chaînes littérales.
    Certaines de ces chaînes sont dynamiquement modifiées.

    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
    #define LEVELS  10
    
    #define MENU_PROMPT_ROOT "[E]xit    [H]elp       [S]how         [D]ump ___________________"
    ...
    #define MENU_PROMPT_MEMY "[<]Back   [A]rray ____________________________"
    
    #define LV_ROOT 0
    ...
    #define LV_ATTY 8
    #define LV_STRY 9
    
    
    char *menuPrompt[LEVELS]=
    {
    MENU_PROMPT_ROOT,
    ...
    MENU_PROMPT_MEMY,
    MENU_PROMPT_MEMY
    };
    
    menuPrompt[LV_ATTY][23]='[';
    Bon pour du malloc, dommage je l'aimais bien cette souplesse d'assignation

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 14
    Par défaut
    Résolu par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    char menuPrompt[LEVELS][66]=
    {
    MENU_PROMPT_ROOT,
    ...
    MENU_PROMPT_MEMY,
    MENU_PROMPT_MEMY
    };
    En revanche, cela implique une longueur = 66 char pour toutes les littérales, voire > 66 avec warning du compilateur.
    Et < à 66, ça tappe dans l'inconnu

  6. #6
    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
    Cela implique une longueur inférieure ou égale à 65 (66 avec le caractère de fin de chaine), plutôt ?

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 14
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Pour compléter ce que vient de dire gulain, il faut savoir que quand tu fais ça :
    char *p="Hello", aucun espace mémoire n'est réservé sur le tas comme ce serait le cas avec malloc, ou sur la pile comme ce serait le cas avec le tableau a. La chaine "Hello" est mise dans une zone spécifique de la mémoire où sont placées les constantes. Tu ne peux donc pas modifier les données pointées par p, bien que tu puisses modifier p lui-même.

    Mon échange avec gangsoleil dans cette discussion pourra t'intéresser : http://www.developpez.net/forums/d12...n/#post6770934

    PS : char *p="Hello" est une allocation statique : http://fr.wikipedia.org/wiki/Allocation_de_m%C3%A9moire
    J'ai lu cette discussion, merci ; et sans vouloir insister cela fut il toujours le cas ?
    En effet, j'ai souvenir du compilateur Turbo C qui autorisait ce genre de réécriture !

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 119
    Par défaut
    Citation Envoyé par CyrIng Voir le message
    J'ai lu cette discussion, merci ; et sans vouloir insister cela fut il toujours le cas ?
    En effet, j'ai souvenir du compilateur Turbo C qui autorisait ce genre de réécriture !
    Le comportement n'est pas défini, ça veut dire que le compilateur fait ce qu'il veut, en particulier il peut faire en sorte que tu puisses modifier ces chaînes de caractères (c'était peut-être le cas de Turbo C, je n'en sais rien).

  9. #9
    Membre chevronné

    Profil pro
    Inscrit en
    Août 2007
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 179
    Par défaut
    Sinon il y a strdup de la bibliothèque string.h qui fait à la fois l'allocation mémoire et l'assignation

    Si tu remplaces
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *p=strdup("Hello")
    tu n'auras plus ton erreur de segmentation

    Cette fonction n'est pas standard, mais malgré tout assez portable puisque POSIX.1.

Discussions similaires

  1. Segfault sur un int?
    Par lguignar dans le forum Débuter
    Réponses: 9
    Dernier message: 18/07/2008, 10h03
  2. Segfault sur un int?
    Par lguignar dans le forum C++
    Réponses: 9
    Dernier message: 18/07/2008, 10h03
  3. Segfault sur contructeur de string
    Par lemmel dans le forum SL & STL
    Réponses: 7
    Dernier message: 02/09/2007, 13h50
  4. Avis sur un cas simple de diagramme de classe
    Par arnobidul dans le forum Diagrammes de Classes
    Réponses: 8
    Dernier message: 01/08/2007, 09h07
  5. [LG]plantage sur une commande basique !
    Par Jeff on the web dans le forum Langage
    Réponses: 5
    Dernier message: 13/01/2004, 19h07

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