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

Langage C++ Discussion :

warning "deprecated conversion from string constant to 'char*'


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2014
    Messages
    15
    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 : 15
    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

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 : 5 202
    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]

  3. #3
    Membre Expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    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 856
    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.

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2014
    Messages
    15
    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 : 15
    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
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    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

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 : 5 202
    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;
    }

  7. #7
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2014
    Messages
    15
    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 : 15
    Par défaut
    bonjour,
    j' ai étudié les pointeurs et l' allocation dynamique de tableaux afin de retravailler le code que je vous avais montré ainsi j' ai de nouveau des problèmes au niveau de
    memcpy car il est nécessaire de mettre un type void * mais je voudrais mettre en paramètre un tableau. Peut on mettre deux tableaux en paramètres dans memcpy?
    Merci d' avance
    En fait la fonction permet de diviser un tableau data en plusieurs petit tableau, voici le code que j' ai retravaillé
    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
    30
    31
    32
    33
    34
    char dimensionnement_de_data_a_envoyer(bool liberation, char data[],unsigned int taille_de_data,unsigned int taille_desiree)
    {
    char tampon[1500];
    int i,j,nombre_de_fois
    int taille_de_data;***** 
             if (taille_de_data==0)
                     return "";
            if (taille_desiree>1500)
                    taille_desiree=1500;
    // ********************************************************
    // Dimensionne les data
    // ********************************************************
            if(taille_desiree==0)
                   sprintf(tampon,"");
           else{
                  nombre_de_fois=taille_de_data/taille_desiree;
                              for (i=1 ; i<=nombre_de_fois ; i++){
                                              for (j=0 ; j<taille_desiree ; j++){
                                             memcpy(tampon[j],data[j],taille_desiree);
                                             cout<<tampon[j]<<endl; }
                              memcpy(tampon[j+i*taille_desiree],data[j+i*taille_desiree],taille_desiree);
                             cout << tampon[j+i*taille_desiree]<<endl;
                             }
     
     
           if (liberation==TRUE)
         liberation_du_jeton(); // Rend la main à la fenêtre principale
              }
    if (taille_de_data-(nombre_de_fois*taille_desiree)!=0)
    memcpy(tampon[(nombre_de_fois*taille_de_data)+1],data[nombre_de_fois*taille_desiree+1,taille_de_data-(nombre_de_fois*taille_desiree));
    tampon[taille_desiree]=0;
    }
    return(tampon);
    }

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