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 :

Overflow sur string ?


Sujet :

C

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Décembre 2017
    Messages : 26
    Par défaut Overflow sur string ?
    Bonjour,

    Les "strings" en C continuent de me jouer des tours, voyez l'exemple suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char * str;
    str = "0123456789";
    printf("Le caractère en 3ème position est: %c\n", str[2]); /* Affiche 2 */
    str[2] = '*'; /* Erreur de segmentation */
    L'affectation du caractère '*' au 3ème élément de ma chaîne me génère une erreur de segmentation à l'exécution, aucune erreur de compilation.

    S'agirait-il d'un overflow parce que je ne réserve qu'un pointeur char vers le début de la chaîne ? Le compilateur n'alloue-t-il pas la bonne quantité de mémoire automatiquement ? En effet, quand je définis str il ne pointe nulle part. Mais quand j'affecte la chaîne à ce pointeur, la chaine étant un tableau, str a pour valeur le pointeur vers le premier élément de type char. Le compilateur ne devrait-il pas allouer lui-même l'espace nécessaire pour le reste de la chaine ?

    Merci d'avance pour votre éclairage !

    Sébastien

  2. #2
    Membre émérite
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Juillet 2020
    Messages
    352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Juillet 2020
    Messages : 352
    Par défaut
    Bonjour,
    les chaines littérales comme "0123456789" sont stockées dans un espace mémoire en lecture seule, elles sont immutables = on ne peut les modifier. Or tu crées un pointeur vers cette chaîne, tu essayes de la modifier et du coup il y a une violation d'accès ⇒ ça plante.

    Pour pallier ce problème, tu pourrais déclarer un tableau de char, demander au compilo d'y copier le littéral et tout se passera mieux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    char str[] = "0123456789";
    printf("Le caractère en 3ème position est: %c\n", str[2]); /* Affiche 2 */
    str[2] = '*'; /* Ça passe */
    Tu peux également, si tu as un gcc récent, ajouter en plus des warnings une option d'analyse statique. Cela te permettra de déceler ces erreurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ gcc -Wall -Wextra -fanalyzer -g -c test.c
    In function ‘main’:
    test.c:8:16: warning: write to string literal [-Wanalyzer-write-to-string-literal]
        8 |         str[2] = '*'; /* Erreur de segmentation */
          |         ~~~~~~~^~~~~
      ‘main’: event 1
        |
        |
    ou alors, demander à un outil spécialisé de profilage mémoire, comme valgrind, d'essayer de débusquer l'erreur :
    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
    $ valgrind --leak-check=full --track-origins=yes --show-reachable=yes ./test
    ==159839== Memcheck, a memory error detector
    ==159839== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==159839== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
    ==159839== Command: ./test
    ==159839== 
    Le caractère en 3ème position est: 2
    ==159839== 
    ==159839== Process terminating with default action of signal 11 (SIGSEGV): dumping core
    ==159839==  Bad permissions for mapped region at address 0x10A00A
    ==159839==    at 0x109178: main (test.c:8)
    ==159839== 
    ==159839== HEAP SUMMARY:
    ==159839==     in use at exit: 0 bytes in 0 blocks
    ==159839==   total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
    ==159839== 
    ==159839== All heap blocks were freed -- no leaks are possible
    ==159839== 
    ==159839== For lists of detected and suppressed errors, rerun with: -s
    ==159839== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
    Segmentation fault (core dumped)
    ou encore, après avoir compilé ton programme en demandant une vérification des accès mémoire ainsi : gcc -Wall -Wextra -fanalyzer -fsanitize=address -g -o test test.c obtenir des informations lors du crash :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $ ./test
    Le caractère en 3ème position est: 2
    AddressSanitizer:DEADLYSIGNAL
    =================================================================
    ==159859==ERROR: AddressSanitizer: SEGV on unknown address 0x556beb037022 (pc 0x556beb036240 bp 0x7ffe8c10e450 sp 0x7ffe8c10e440 T0)
    ==159859==The signal is caused by a WRITE memory access.
        #0 0x556beb036240 in main /home/fred/Desktop/test.c:8
        #1 0x7f61b0697b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #2 0x556beb0360cd in _start (/home/fred/Desktop/test+0x10cd)
     
    AddressSanitizer can not provide additional info.
    SUMMARY: AddressSanitizer: SEGV /home/fred/Desktop/test.c:8 in main
    ==159859==ABORTING
    Apprendre à utiliser ces outils (en plus d'un debuger) est indispensable, surtout quand tu développes en C.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Décembre 2017
    Messages : 26
    Par défaut
    Bonjour WhiteCrow, merci d'avoir pris le temps de me répondre de manière aussi complète !

    Je comprends mieux pourquoi je pouvais lire la valeur mais pas la modifier.

    Merci aussi pour les options du compilateur qui permettent de débusquer ces problèmes.

    Excellente journée !

    Sébastien

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

Discussions similaires

  1. Probleme d'overflow sur le port série
    Par jimay dans le forum MATLAB
    Réponses: 2
    Dernier message: 29/03/2007, 11h23
  2. Problème vidéo et overflow sur Mac
    Par gregmab dans le forum Mise en page CSS
    Réponses: 1
    Dernier message: 22/02/2007, 18h28
  3. [XHTML][CSS] Overflow sur DIV sans taille déterminée
    Par pingos dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 20/08/2006, 15h37
  4. tests sur String
    Par frouge dans le forum Collection et Stream
    Réponses: 1
    Dernier message: 07/06/2006, 11h38
  5. Caster un objet sur string !!
    Par maximus001ma dans le forum Langage
    Réponses: 3
    Dernier message: 06/06/2006, 13h02

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