1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    septembre 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : septembre 2014
    Messages : 14
    Points : 10
    Points
    10

    Par défaut warning "deprecated conversion from string constant to 'char*'

    bonjour,
    voilà j' ai quelques soucis je compile avec mingw et je rencontre des problèmes lors de la compilation de mon programme, j' ai un warning "deprecated conversion from string constant to 'char*'" s' affiche à la ligne "return "";"de mon programme. J' ai cherché sur internet le warning qui me dit que la conversion d' un string vers un pointeur de caractères est obsolète mais je ne sais pas par quoi remplacer dans ma ligne de code, le code de ma fonction est :
    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
    char * dimensionnement_de_data_a_envoyer(bool liberation, char data[65535],unsigned int taille_de_data,unsigned int taille_desiree)
    {
          char tampon[65535];
          int i,nombre_de_fois;
    if (taille_de_data==0)
         return "";
    if (taille_desiree>65000)
         taille_desiree=65000;
    if(taille_desiree==0)
         sprintf(tampon,"");
    else
    {
    nombre_de_fois=taille_desiree/taille_de_data;
              for (i=0;i<nombre_de_fois;i++)
              {
                       memcpy(tampon+i*taille_de_data,data,taille_de_data);
                       if (liberation==TRUE)
                       liberation_du_jeton(); 
              }
      if (taille_desiree-(nombre_de_fois*taille_de_data)!=0)
      memcpy(tampon+(nombre_de_fois*taille_de_data),data,taille_desiree-(nombre_de_fois*taille_de_data));
      tampon[taille_desiree]=0;
    }
    return(tampon);
    }
    Je voudrais savoir sinon si quelqu' un connaissait un site pour connaître la signification des warnings si possible en français , j' ai du mal à trouver des infos sur le net par exemple que signifie"zero-length ms_printf format string" ou bien "address of local variable 'tampon' returned".
    Je vous remercie de m' aider

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    4 609
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : juin 2007
    Messages : 4 609
    Points : 14 555
    Points
    14 555

    Par défaut

    Ta fonction retourne "tampon", mais prétends retourner un char*. C'est une erreur de constance.
    "tampon" est un "littéral de chaine de caractère" son type est const char [].

    Il y a cependant beaucoup plus grave, ta fonction retourne la valeur tampon.
    Comme c'est un tableau, son nom est convertible en l'adresse de son premier élément, jusque là, pas de problème.
    Il se trouve que c'est un tableau local de la fonction, donc, sa mémoire est libérée à la sortie de la fonction, comme toute variable locale.
    La valeur retournée est donc un pointeur sur de la mémoire libérée (donc invalide).
    Utiliser cette valeur (par une affectation, un memcpy ou autre) provoque un comportement indéfini.
    Les cas fréquents sont:
    • Ca fonctionne quand même, manque de chance.
    • Le programme crashe pour "stack corruption"
    • Le programme lit autre chose, car la mémoire en question a été modifiée. (stack/buffer overflow)


    Utilise std::string, et tu n'auras plus ces problèmes.
    Tout est beaucoup plus clair avec ce type standard conçu précisément dans ce but

    PS: pour écrire du code, utilise les balises [code] ou [c]
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Membre expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mars 2011
    Messages
    1 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : mars 2011
    Messages : 1 718
    Points : 3 200
    Points
    3 200

    Par défaut

    Salut,

    ta chaine vide est un literal (const char*) alors que ta fonction est censée renvoyer un simple pointeur (char*).

    A noter que ton autre return renvoie l'adresse d'un buffer local à la fonction, attention au good/bad behavior (c'est ce qui te lèves le warning "address of local variable 'tampon' returned").

    D'un point de vue général pour les messages d'erreur, si tu comprends un peu l'anglais tu dois pouvoir t'en sortir (cf. ma remarque précédente). Et si tu ne sais pas tu peux le c/c directement dans google pour avoir les info qui vont bien (mais ce sera aussi sûrement en anglais).

    Pour l'autre warning remonté ("zero-length ms_printf format string") on peut traduire par "ms_printf n'aime pas avoir une chaine vide comme format", format devant correspondre au premier (ex. printf) ou deuxième (ex. sprintf) paramètre de la fonction (je ne connais pas ms_printf).

    Et aussi tu devrais faire du pur C++, ou on va te tomber dessus

    PS : pense à utiliser les balises CODE pour tes extraits de code, c'est bien plus lisible.
    Plus je connais de langages, plus j'aime le C.

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    septembre 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : septembre 2014
    Messages : 14
    Points : 10
    Points
    10

    Par défaut

    je voulais vous remercier de m' avoir donné de votre temps pour m' aider, j' ai bien pris note de ce que vous m' avez dit en utilisant la bibliothèque std::string
    et en modifiant le type de retour de la fonction cependant vous m' avez dit que la fonction retournais un tableau mais que ses valeurs n' étaient pas mémorisé,
    si je comprends il faut qu' au lieu à la fin de mettre
    mettre par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcpy(tampon,data,taille_de_data)
    sinon pour le reste la fonction se présente maintenant comme suit:
    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
    std::string *dimensionnement_de_data_a_envoyer(bool liberation, const char data[65535],unsigned int taille_de_data,unsigned int taille_desiree)
    {
         std::string *tampon=new string[65535];
         int i,nombre_de_fois;
         std::string none="";
     
       if (taille_de_data==0)
        return '\0';
     
    if (taille_desiree>65000)
    taille_desiree=65000;
     
    if(taille_desiree==0)
    memcpy(tampon,"",0);
    else
        {
          nombre_de_fois=taille_desiree/taille_de_data;
          for (i=0;i<nombre_de_fois;i++)
                 {
                  memcpy(tampon+i*taille_de_data,data,taille_de_data);
                  if (liberation==TRUE)
                  liberation_du_jeton(); 
                 }
          if (taille_desiree-(nombre_de_fois*taille_de_data)!=0)
          memcpy(tampon+(nombre_de_fois*taille_de_data),data,taille_desiree-(nombre_de_fois*taille_de_data));
          tampon[taille_desiree]=="0";
        }
    return(tampon);
    }
    Merci encore pour votre aide

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    Consultant informatique
    Inscrit en
    octobre 2004
    Messages
    10 410
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : octobre 2004
    Messages : 10 410
    Points : 22 267
    Points
    22 267

    Par défaut

    Salut,

    D'abord, une petite précision quand même : std::string n'est pas une bibliothèque, c'est une des (nombreuses) fonctionnalités proposées par la bibliothèque standard.

    Pour être précis, il s'agit d'une classe, c'est à dire, d'un concept destiné à rendre "un certain nombre" (très nombreux, en ce qui concerne la classe std::string) de services au travers de fonctions qui peuvent accéder à "un certain nombre" de données "cachées" (ou, pour être plus précis, auquel auxquelles le langage nous empêche d'accéder parce que les concepteurs les ont mises dans une accessibilité restreinte).

    Mais ce qui est chouette, c'est qu'elle correspond au final à un "package tout compris" destiné à la manipulation des chaines de caractères. Le principal inconvénient étant sans doute qu'il faut accepter de renoncer aux fonctions issues du C pour manipuler les chaines de caractères. Or, memcpy, c'est une fonction issue du C, destinée à manipuler la "notion de chaine de caractères" telle qu'elle est envisagée en C. Et cette manière est fondamentalement différente de la manière dont la notion de chaine de caractères est envisagée en C++, entre autres, parce qu'elle se limite au stricte minimum en C, à savoir : un ensemble de caractères qui se suivent en mémoire, alors que l'utilisateur de la classe std::string pourrait même carrément ignorer que c'est le cas.

    De plus, comme je te l'ai dit, la classe std::string fournit un service tout compris, ce qui inclut la gestion de la mémoire nécessaire à la représentation de l'ensemble des caractères qui composent la chaine (en veillant, à la fois à ce que cet espace soit alloué au bon moment, en étant suffisant et à ce qu'il soit libéré au bon moment). Tu n'as donc absolument plus aucune raison de manipuler une instance de cette classes sous forme de pointeur.

    (une petite aparté, au passage : en C++, l'utilisation des pointeurs se limite généralement aux cas où l'on n'a vraiment pas d'autre choix, et tous ces cas surviennent dans des circonstances qui n'apparaissent que lorsque l'on a affaire à une hiérarchie de classes... A l'héritage public et à ce qu'il permet )

    Par contre, étant donné les ressources qui sont nécessaires à la copie des chaines de caractères, il est fréquent que l'on décide de les transmettre sous forme de référence (éventuellement constante) aux fonction qui en demandent comme paramètre...
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    4 609
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : juin 2007
    Messages : 4 609
    Points : 14 555
    Points
    14 555

    Par défaut

    Ton code souffre de quelques problèmes:
    • la taille d'un tableau en argument n'est pas utilisée par le compilateur, le tableau effectivement transmis peut être plus grand ou plus petit.
    • std::string *tampon=new string[65535]; alloue un tableau sur le tas de 65535 chaines de caractères.
    • tu ne devrait probablement pas libérer le jeton à chaque itération dans la boucle, mais après.
    • si taille_desiree (ou taille_data) vaut 0, le jeton n'est jamais libéré.
    • Tu ne devrais définir une variable que lorsqu'elle devient utile


    A mon avis, la libération devrait être faite par l'appelant, qui sait lui-même si elle doit être faite.

    Une première approche façon C++ serait la suivante:
    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
    std::string dimensionnement_de_data_a_envoyer(std::string const& data, std::string::size_type taille_desiree) {
      if (data.empty() || taille_desiree==0) return "";
     
      if (taille_desiree>65000) taille_desiree=65000;
     
      std::string resultat;
      resultat.reserve(taille_desiree);
      while (resultat.size() + data.size() <= taille_desiree) {
        resultat.append(data); // ou resultat += data;
      }
     
      auto difference = taille_desiree - resultat.size();
      if (difference > 0) {
        resultat.append( data.substr(0,difference) );
      }
     
      return resultat;
    }
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

Discussions similaires

  1. Réponses: 6
    Dernier message: 14/09/2016, 08h07
  2. Réponses: 13
    Dernier message: 27/03/2013, 10h43
  3. Réponses: 3
    Dernier message: 04/05/2010, 08h58
  4. Réponses: 2
    Dernier message: 08/12/2009, 12h57
  5. error: invalid conversion from `const wxChar*' to `CHAR*'
    Par barbarello dans le forum wxWidgets
    Réponses: 16
    Dernier message: 31/01/2006, 11h28

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