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 :

Segmentation fault avec strcpy()


Sujet :

C++

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2011
    Messages : 21
    Par défaut Segmentation fault avec strcpy()
    Bonjour,

    J'ai un problème avec ce code qui provoque une erreur de segmentation au niveau de la fonction strcpy() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    char *Text=new char[9];
    if(Text!=0)
    {
         memset(&Text,0,sizeof(Text));
         strcpy(Text,"01234567");
         delete[] Text;
    }
    Et je ne comprends pas pourquoi TextSz n'est pas égal à 9 dans cet exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    char *Text=new char[9];
    if(Text!=0)
    {
         int TextSz=sizeof(Text);
         delete Text[];
    }
    D'avance merci de votre aide.

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    pour ton premier cas, tu donnes l'adresse de Text en paramètre à memset, il va donc remplacer la valeur pointée, soit le pointeur vers le char*.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    char *Text=new char[9];
    if(Text!=0)
    {
         memset(&Text,0,sizeof(Text)); // l'adresse de text est maintenant 0
         strcpy(Text,"01234567"); // tu essayes donc de copier la chaîne à l'emplacement mémoire 0
         delete[] Text; // delete 0 ne plantera pas mais la mémoire allouée ne sera pas libéré
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    char *Text=new char[9];
    if(Text!=0)
    {
         memset(Text,0,sizeof(Text));
         strcpy(Text,"01234567");
         delete[] Text;
    }
    memset prend un pointeur et affectera la mémoire pointée, Text est déjà un pointeur, qui pointe sur les 9 char alloués.

    deuxième problème:
    Text* est un pointeur sur char*, sizeof te retourne la taille d'un char*, indépendament du fait que derrière se cache un char, char[2] ou char[4000].


    ps: C++ => std::string.
    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
    Membre actif
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2011
    Messages : 21
    Par défaut
    ça veut dire que la mémoire allouée lors des essais n'a pas été libérée ?

    Etant donné que je travaille avec des chaînes de caractères de 65536 octets, ça fait beaucoup de mémoire perdue.

    Est-ce que la mémoire reste allouée à la fin de l'exécution du programme ou y'a-t-il un ramasse-miettes intégré au système ?

    Pour info je développe sous Debian 2.6.32-5-686.

  4. #4
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par défaut
    Citation Envoyé par tasna Voir le message
    ça veut dire que la mémoire allouée lors des essais n'a pas été libérée ?
    D'après le code que tu nous as donné, si. L'opérateur delete (ou delete[]) "sait" combien d'octets ont été alloués dans Text. Si tu oublies de les appeler, alors la mémoire restera utilisée jusqu'à la fin du programme.

    Ton code fonctionnerait si tu avais écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char Text[9];
    memset(Text, 0, sizeof(Text));
    strcpy(Text, "01234567");
    ou :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char* Text = new char[9];
    memset(Text, 0, sizeof(char)*9); // Car ici sizeof(Text) vaut 4 ou 8 (la taille du pointeur), mais pas la taille de la chaîne
    strcpy(Text, "01234567");
    delete[] Text;
    ou, quand même vachement mieux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::string Text;
    Text = "01234567";

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2011
    Messages : 21
    Par défaut
    Oui mais mon memset() avait changé l'adresse sur 0.

    Mais du moment que la mémoire est libérée à la fin de l'exécution du programme ça m'arrange. Je n'aurais pas a éteindre mon PC.

    Bon je me lance...
    Qu'est ce que c'est std:: ?
    De la STL ?
    Est qu'est ce que la STL ?

  6. #6
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par défaut
    Citation Envoyé par tasna Voir le message
    Oui mais mon memset() avait changé l'adresse sur 0.
    Tout à fait. Ton exemple plante sur le strcpy, mais la mémoire est néanmoins toujours libérée à la sortie du programme (en principe ça dépend du système d'exploitation, mais c'est le cas pour Windows et linux).

    Citation Envoyé par tasna Voir le message
    Mais du moment que la mémoire est libérée à la fin de l'exécution du programme ça m'arrange. Je n'aurais pas a éteindre mon PC.
    Ca dépend de ton programme. Si tu fais du traitement lourd, alors il y aura nécessairement un moment ou tu n'auras plus de mémoire disponible, et là tout fout le camp. Si c'est juste un petit programme, oui ça passera. C'est très moche, et je te déconseille de prendre cette mauvaise habitude, mais ça fonctionnera.

    Citation Envoyé par tasna Voir le message
    Bon je me lance...
    Qu'est ce que c'est std:: ?
    De la STL ?
    Est qu'est ce que la STL ?
    J'ai comme un doute : tu programmes bien en C++ ?
    La STL est l'acronyme de "Standard Template Library". C'est un morceau de la bibliothèque standard du C++, qui constitue je pense l'un des plus gros atouts du langage. Comme tu peux le voir dans l'exemple ci-dessus, utiliser la STL te permet bien souvent de faire la même chose qu'en C avec moitié moins de code (et donc au minimum deux fois moins d'erreurs).
    Le préfixe std:: est un namespace (espace de nommage) réservé à la STL, dans lequel tu trouveras beaucoup de classes très utiles, comme ici string.
    Si tu veux en apprendre plus, je te conseille de lire la FAQ sur la STL.

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2011
    Messages : 21
    Par défaut
    D'accord sur le fait que la mémoire est libérée à la fin de l'exécution du programme mais dans un post tu avais dit que dans mon code le delete[] avait désalloué la mémoire ce qui me semble bizarre puisque le memset() à changé l'adresse sur 0.

    Concernant mon langage de programmation je dirais du C avec du C++.
    Des booléens, des ++, etc...

    Bon je ne connais pas beaucoup de différences entre le C et le C++.

    Franchement je préfère utiliser les bons vieux strcpy(), strcat(), strlen(), etc... que des classes dont je ne sais pas grand choses sur leur performances.

    La seule chose que je sais c'est que l'utilisation de classes permet de développer plus vite en produisant moins de code.

    Je me rappelle avoir utilisé le namespace std pour ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include <Windows.h>
     
    using namespace std;
     
    int main(void)
    {
         char cDstIpv4Addr[16];
         cin >> cDstIPv4Addr;
         ...
         ...
         return 0;
    }
    STOP !!! Je plaisantais pour :

    Je me rappelle aussi avoir utilisé les vecteurs pour des tableaux multidimensionnels dynamiques.

  8. #8
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par tasna Voir le message
    Franchement je préfère utiliser les bons vieux strcpy(), strcat(), strlen(), etc... que des classes dont je ne sais pas grand choses sur leur performances.
    Et que sais tu des performances de ces bonnes vieilles fonctions ? Bas niveau ne veux pas dire performant. Quand on est trop bas niveau, on se prise d'optimisations qu'un peu de hauteur de vue permettrait.

    Quelques informations sur les performances de std::string :
    - Sans que tu n'y fasse rien, string est optimisé pour que les très petites chaînes de caractère soient gérées sans faire la moindre allocation dynamique de mémoire. Peux-tu en dire autant de ton code ?
    - Sans que tu n'y fasse rien, string est optimisé pour diminuer le nombre de réallocation mémoire quand tu concatène plusieurs chaînes à la suite les unes des autres, choses que ne fait pas strcat.
    - strlen s'exécute en temps linéaire en fonction de la taille de la chaîne. string::size() s'exécute en temps constant.


    Sans compter la facilité d'utilisation (la preuve en étant que ton code initial est buggé), le fait que ça marche bien en présence d'exceptions...

    Le seul "piège" de performances de std::string est qu'il est tellement facile à manier qu'il est possible pour un novice de ne pas se rendre compte qu'il est en train de copier un string alors que la copie n'est pas nécessaire.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2011
    Messages : 21
    Par défaut
    Et que sais tu des performances de ces bonnes vieilles fonctions ?
    Pas grand chose. Je sais qu'elles sont présentes sur tous les systèmes populaires Windows, distros Linux (déjà ça). Elles sont natives et ne font pas partie d'une quelconque bibliothèque à part.

    Bas niveau ne veux pas dire performant.
    Après ça dépend du développeur mais en général le code bas niveau fait le strict minimum.

    Quand on est trop bas niveau, on se prise d'optimisations qu'un peu de hauteur de vue permettrait.
    Que veux-tu optimiser dans une fonction bas niveau qui compte le nombre de caractères d'une chaîne et retourne ce nombre ?
    Que veux-tu optimiser dans une fonction qui copie une chaîne de caractères, caractère par caractère ?

    Sans que tu n'y fasse rien, string est optimisé pour que les très petites chaînes de caractère soient gérées sans faire la moindre allocation dynamique de mémoire. Peux-tu en dire autant de ton code ?
    Pour les petites chaînes de caractères j'utilise une variable statique.

    Sans que tu n'y fasse rien, string est optimisé pour diminuer le nombre de réallocation mémoire quand tu concatène plusieurs chaînes à la suite les unes des autres, choses que ne fait pas strcat.
    En clair ?

    Qu'aurais-je à gagner avec les std::string par rapport à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    char SendBuffer[8193];
    memset(&SendBuffer,0,sizeof(SendBuffer));
    strcpy(SendBuffer,"GET /update HTTP/1.1\n");
    strcat(SendBuffer,"Host: example.com\n");
    strcat(SendBuffer,"Accept: text/plain\n\n");
    int SendBufferLen=strlen(SendBuffer);
    int rsend=send(rsocket,SendBuffer,SendBufferLen,0);
    ...
    ...
    Si tu as un meilleur code, plus simple et plus performant, je t'écoute.

    strlen s'exécute en temps linéaire en fonction de la taille de la chaîne. string::size() s'exécute en temps constant.
    Franchement je ne vois pas par quel miracle c'est possible...
    Si je comprends bien, string::size s'exécute aussi vite avec une chaîne de caractères de 1B qu'avec une de 65536B ?

    Sans compter la facilité d'utilisation (la preuve en étant que ton code initial est buggé), le fait que ça marche bien en présence d'exceptions...
    string::append est aussi facile qu'un strcat()

    Quel code est buggé ?

  10. #10
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par tasna Voir le message
    Pas grand chose. Je sais qu'elles sont présentes sur tous les systèmes populaires Windows, distros Linux (déjà ça). Elles sont natives et ne font pas partie d'une quelconque bibliothèque à part.
    std::string n'est ni plus ni moins natif que strcat en C++. Les deux font partie de la bibliothèque standard et sont disponibles dès qu'un compilateur C++ raisonnable existe
    Citation Envoyé par tasna Voir le message
    Que veux-tu optimiser dans une fonction bas niveau qui compte le nombre de caractères d'une chaîne et retourne ce nombre ?
    Ne pas faire le calcul parce que tu as conservé le résultat en mémoire
    Citation Envoyé par tasna Voir le message
    Que veux-tu optimiser dans une fonction qui copie une chaîne de caractères, caractère par caractère ?
    La gestion des allocation mémoire qui va de paire avec cette copie
    Citation Envoyé par tasna Voir le message
    Pour les petites chaînes de caractères j'utilise une variable statique.
    Pour une chaîne saisie par l'utilisateur, comment sais-tu au moment où tu écris le code si elle sera petite ou grande ?
    Citation Envoyé par tasna Voir le message


    En clair ?

    Qu'aurais-je à gagner avec les std::string par rapport à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    char SendBuffer[8193];
    memset(&SendBuffer,0,sizeof(SendBuffer));
    strcpy(SendBuffer,"GET /update HTTP/1.1\n");
    strcat(SendBuffer,"Host: example.com\n");
    strcat(SendBuffer,"Accept: text/plain\n\n");
    int SendBufferLen=strlen(SendBuffer);
    int rsend=send(rsocket,SendBuffer,SendBufferLen,0);
    ...
    ...
    Si tu as un meilleur code, plus simple et plus performant, je t'écoute.
    Dans ce cas, j'ai plus simple et plus performant sans utiliser les std::string...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char const SendBuffer[] = "GET /update HTTP/1.1\n"
        "Host: example.com\n"
        "Accept: text/plain\n\n";
    int rsend=send(rsocket,SendBuffer,sizeof(SendBuffer),0);
    ...
    Citation Envoyé par tasna Voir le message


    Franchement je ne vois pas par quel miracle c'est possible...
    Si je comprends bien, string::size s'exécute aussi vite avec une chaîne de caractères de 1B qu'avec une de 65536B ?
    Oui. Car la longueur est calculée une bonne fois pour toutes et stockée dans la chaîne
    Citation Envoyé par tasna Voir le message
    string::append est aussi facile qu'un strcat()
    Alors, déjà, string::apend est très rarement appelé en direct, on utilisera plus généralement + ou +=.
    Ensuite, c'est bien plus simple à gérer qu'un strcat, car ça s'occupe tout seul de la gestion de la mémoire. Quand tu veux faire un strcat entre deux chaînes dont tu ne connais pas a priori la longueur, tu dois :
    • Calculer la longueur de chaque chaîne
    • Vérifier que le buffer alloué pour la première chaîne (dont tu dois gérer la taille séparément, un argument de plus pour tes fonctions...) est suffisamment grand pour contenir les deux chaînes.
    • Si ce n'est pas le cas :
      • allouer de la mémoire pour stocker le résultat
      • Vérifier que cette allocation mémoire n'a pas échoué, si jamais tu la fais avec malloc au lieu de la faire avec new, et gérer cet échec
      • Recopier la première chaîne dans la zone nouvellement allouée
      • Nettoyer la mémoire occupée par la première chaîne.
    • Enfin, appeler strcat
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  11. #11
    Membre actif
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2011
    Messages : 21
    Par défaut
    La gestion des allocation mémoire qui va de paire avec cette copie.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    int StrCpy(char DstStr[], char SrcStr[], int nChr)
    {
         int StrIx=0;
         while(SrcStr[StrIx]!=0 && StrIx!=nChr)
         {
              DstStr[StrIx]=SrcStr[StrIx];
              ++StrIx;
         }
         return StrIx;
    }
    Quelle gestion des allocations mémoire ?
    La copie avec string::copy fait mieux ?

    Pour une chaîne saisie par l'utilisateur, comment sais-tu au moment où tu écris le code si elle sera petite ou grande ?
    fgets()

    char const SendBuffer[] = "GET /update HTTP/1.1\n"
    "Host: example.com\n"
    "Accept: text/plain\n\n";
    Des fois j'ai besoin d'ajouter le nom d'hôte pendant l'exécution, donc ça ne va pas.

    Oui. Car la longueur est calculée une bonne fois pour toutes et stockée dans la chaîne
    Tu veux dire, à la compilation ?
    Mais pour des chaînes reçues par socket par exemple. La longueur est inconnue de string::size donc il faut bien qu'il la calcule en la parcourant caractère par caractère jusqu'à \0.

    Alors, déjà, string::apend est très rarement appelé en direct, on utilisera plus généralement + ou +=.
    Je préfère garder les + et les += pour les opérations mathématiques.

    Quand tu veux faire un strcat entre deux chaînes dont tu ne connais pas a priori la longueur
    ça m'arrive très très rarement de ne pas connaître la longueur d'une chaîne.

    Vérifier que le buffer alloué pour la première chaîne (dont tu dois gérer la taille séparément, un argument de plus pour tes fonctions...) est suffisamment grand pour contenir les deux chaînes.
    Mes buffers sont toujours assez grands. Mais pas trop.


    Mais bon, qu'est ce que j'y gagne d'important à utiliser la STL ?
    Quelques millisecondes gagnées ou plus ?
    Est-ce que ça vaut le coup que je change mes conventions d'écriture pour utiliser la STL ?

  12. #12
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par tasna Voir le message
    La gestion des allocation mémoire qui va de paire avec cette copie.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    int StrCpy(char DstStr[], char SrcStr[], int nChr)
    {
         int StrIx=0;
         while(SrcStr[StrIx]!=0 && StrIx!=nChr)
         {
              DstStr[StrIx]=SrcStr[StrIx];
              ++StrIx;
         }
         return StrIx;
    }
    Quelle gestion des allocations mémoire ?
    La copie avec string::copy fait mieux ?
    Le problème n'est pas le fonctionnement de la fonction en elle-même mais le fait que tu dois lui fournir un tableau de taille suffisante. Ce qui passe facilement par une allocation dynamique si tu ne sais pas déterminer la taille à priori.
    Et quand tu commences à concaténer différentes chaînes sans connaître le nombre et la taille à priori et que tu gères les allocations qui vont bien avec une croissance pas trop couteuse, etc. C'est vite galère et dans du code "tout venant" c'est au mieux peu efficace et au pire pas robuste (c'est bien entendu possible d'avoir un code robuste et efficace, mais ça demande un certain effort et je me demande de plus en plus, en voyant ce qu'arrive à pondre certaines personnes, si c'est vraiment à la portée de tout le monde).

    Citation Envoyé par tasna Voir le message
    Pour une chaîne saisie par l'utilisateur, comment sais-tu au moment où tu écris le code si elle sera petite ou grande ?
    fgets()
    Et donc tu tronques s'il saisit une chaîne plus grande que ton tableau !

    Citation Envoyé par tasna Voir le message
    Oui. Car la longueur est calculée une bonne fois pour toutes et stockée dans la chaîne
    Tu veux dire, à la compilation ?
    Mais pour des chaînes reçues par socket par exemple. La longueur est inconnue de string::size donc il faut bien qu'il la calcule en la parcourant caractère par caractère jusqu'à \0.
    Non au runtime lors de la construction de la chaîne.
    C'est juste une variable qui est mise à jour lorsque tu copies qqch dans ta chaîne, en concatène une autre, etc. Il est trivial et sans coût particulier de connaitre la taille lors de ces opérations, il suffit de mettre à jour ladite variable et ensuite tu y accèdes en temps constant.

    Citation Envoyé par tasna Voir le message
    Quand tu veux faire un strcat entre deux chaînes dont tu ne connais pas a priori la longueur
    ça m'arrive très très rarement de ne pas connaître la longueur d'une chaîne.
    Celles que tu manipules, oui.

    Mais pour une chaîne qui vient de l'extérieur (saisie utilisateur, lecture fichier, réception réseau, etc.) c'est plus compliquée de connaître la taille à l'avance.
    Globalement, il y a troisfaçons de faire :
    • Une taille max et on coupe ce qui dépasse. Mais ce n'est pas toujours acceptable loin de la.
    • Si le traitement si prêtes, on travail par bloc de taille fixe.
    • On gère la croissance de sa chaîne. Ce qui est encapsulé dans std::string.


    Et le troisième cas est, au moins dans mon utilisation, loin d'être marginal.

    Citation Envoyé par tasna Voir le message
    Vérifier que le buffer alloué pour la première chaîne (dont tu dois gérer la taille séparément, un argument de plus pour tes fonctions...) est suffisamment grand pour contenir les deux chaînes.
    Mes buffers sont toujours assez grands. Mais pas trop.
    Idem précédent. Seulement si tu connais la taille à l'avance ou si tu te donnes le droit de tronquer.

    Citation Envoyé par tasna Voir le message
    Mais bon, qu'est ce que j'y gagne d'important à utiliser la STL ?
    Quelques millisecondes gagnées ou plus ?
    Est-ce que ça vaut le coup que je change mes conventions d'écriture pour utiliser la STL ?
    C'est surtout la robustesse et la simplicité que je mettrais en avant.

  13. #13
    Membre actif
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2011
    Messages : 21
    Par défaut
    Oui maintenant je vois ce que tu veux dire en parlant de la variable qui contient la taille de la chaîne. J'avais oublié que c'est une classe et qu'elle peut contenir des variables.

    C'est un argument de poids ! Quand je pense que je pourrais me passer de beaucoup d'appels à strlen()... ça me donne une bonne raison d'utiliser la STL.

    Après au niveau de mon utilisation des chaînes de caractères c'est souvent du 8, 16, 32 ,64 etc... jusqu'à 65536 octets et en général les utilisateurs ne rentrent pas souvent à la main des chaînes de 128 octets.

    L'allocation dynamique m'est plus utile lors de la lecture de fichiers de configuration mais qui met des lignes de 65536 octets ?

    Au bout d'un moment faut savoir dire "Stop, réarrange tes données parce que ça dépasse la capacité de mon buffer".

    Alors je tronque.

    En tout cas, merci beaucoup d'avoir pris le temps de m'expliquer des détails sur la STL. Je pense que je vais m'y mettre sérieusement, surtout que j'ai un gros projet qui m'attend.

    Mais une dernière question; la STL c'est dans quoi ? Dans des fichiers .h ? Dans quoi ?

  14. #14
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Par défaut
    Citation Envoyé par tasna Voir le message
    Oui maintenant je vois ce que tu veux dire en parlant de la variable qui contient la taille de la chaîne. J'avais oublié que c'est une classe et qu'elle peut contenir des variables.

    C'est un argument de poids ! Quand je pense que je pourrais me passer de beaucoup d'appels à strlen()... ça me donne une bonne raison d'utiliser la STL.

    Après au niveau de mon utilisation des chaînes de caractères c'est souvent du 8, 16, 32 ,64 etc... jusqu'à 65536 octets et en général les utilisateurs ne rentrent pas souvent à la main des chaînes de 128 octets.

    L'allocation dynamique m'est plus utile lors de la lecture de fichiers de configuration mais qui met des lignes de 65536 octets ?

    Au bout d'un moment faut savoir dire "Stop, réarrange tes données parce que ça dépasse la capacité de mon buffer".

    Alors je tronque.

    En tout cas, merci beaucoup d'avoir pris le temps de m'expliquer des détails sur la STL. Je pense que je vais m'y mettre sérieusement, surtout que j'ai un gros projet qui m'attend.

    Mais une dernière question; la STL c'est dans quoi ? Dans des fichiers .h ? Dans quoi ?
    si t'as un bon compilateur, il s'agit de la plupart des headers que tu peux atteindre avec les "<>", du style #include <iostream> ou autre..

    Bon courage

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

Discussions similaires

  1. Segmentation fault avec strcmp
    Par FenX. dans le forum Débuter
    Réponses: 6
    Dernier message: 10/08/2007, 08h14
  2. segmentation fault avec wxGLCanvas
    Par Ardeciel dans le forum wxWidgets
    Réponses: 1
    Dernier message: 20/03/2007, 20h13
  3. Probleme de segmentation fault avec sprintf
    Par MathG dans le forum C++
    Réponses: 5
    Dernier message: 14/12/2006, 01h12
  4. Segmentation fault avec glCompressedTexImage2DARB
    Par patbier dans le forum OpenGL
    Réponses: 5
    Dernier message: 12/12/2005, 10h32
  5. Pb segmentation fault avec glutinit()
    Par pipistrelle dans le forum GLUT
    Réponses: 2
    Dernier message: 17/11/2004, 23h17

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