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 :

Récupérer taille allouée d'un char* passé en argument d'une fonction


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut Récupérer taille allouée d'un char* passé en argument d'une fonction
    Bonjour,

    Je souhaiterais récupérer la taille max ou en quelque sorte le "sizeof" d'un char* passé en argument d'une fonction (et donc sans fournir la taille en argument, juste le char*).

    Voici un exemple pour illustrer:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void f(char* str)
    {
      // ici besoin de la taille de str pour y copier une longue chaine de caractère constante
      // du genre strncpy(str, ???, constString);
    }
     
    int main()
    {
      char buf[32];
     
      f(buf);
     
      return 0;
    }
    J'ai essayé plusieurs manières en vain, je précise que je souhaite trouver une solution sans fournie la taille en argument:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void f(char* str, unsigned int size);
    Le problème c'est que je pensais pouvoir récupérer la taille par un sizeof(str) mais cela renvoie la taille d'un pointeur (4 octets).
    Je précise que "buf" est vide ou plutot non-initialisé avant d'être passé à la fonction f(), donc strlen(str) donnera zéro.

    Voilà, donc si vous avez une solution, je suis preneur.

    Merci de votre aide.

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Hello

    Même avec une allocation dynamique (ce qui n'est pas le cas dans ton exemple), il n'y a pas de manière standard de le faire. Même si tu trouves une astuce tordue pour le faire, je le déconseilles fortement.

    Si tes appels sont toujours similaires à ton exemple c'est à dire basé sur des tableaux de char et pas des pointeurs, un template peut te rendre service:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <iostream>
    #include <string>
     
    template <std::size_t Size> std::string char_array_to_str(char const (&arg)[Size]) {
      return std::string(arg, Size);
    }
     
    int main() {
      char roger[3] = {'a','b','c'};
      std::cout << char_array_to_str(roger) << std::endl;
    }

  3. #3
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    Merci pour ton aide.

    Par contre, je ne cherche pas à convertir mon char* en string, je cherche simple à recupérer sa taille pour pouvoir le remplir sans "déborder" la-dite taille.

  4. #4
    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
    Pour commencer, sizeof(n'importe quoi*) = sizeof(void*) = la taille d'un pointeur.
    A la différence d'un tableau (une variable dont le type est truc[]), dont sizeof retournera bien la taille complete.

    Tu peux tenter d'utiliser strlen(), mais cela suppose deux choses: ton pointeur n'est pas nul, ca, tu peux le controler, et le contenu est une chaine de caractères au sens du C: une suite de caractère sans '\0', suivi d'un '\0'.

    Cela dit, un pointeur général ne connais pas de taille.
    Une autre façon de procéder, c'est de passer par la différence entre deux pointeurs... mais il faut les deux pointeurs.

  5. #5
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    Le soucis est que le code C++ sera compilé sous la forme d 'une DLL, et le tableau est fourni (et alloué statiquement du genre char array[1000]) depuis du code Java (qui charde la DLL C++).

    Donc le tableau "reçu" du Java par la DLL est sans doute vide ou plutôt non-initialisé.

  6. #6
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 493
    Par défaut
    Et si c'est correctement designé, l'API doit te fournir la taille du buffer en octet.
    T'aurais pas un peu zappé la documentation de l'API JAVA ?

  7. #7
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    En fait, je vais être plus précis.

    Il s'gait d'une IHM Java qui appelle du JNI pour charger la DLL C++.

    Je m'occupe que du developpement de la DLL C++, donc je doit me comformer aux signatures de fonctions attendues (sans tailles de tableaux, en l'occurence void f(char* str)).

  8. #8
    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
    Donc tu ne peux pas connaitre cette taille par magie.
    Un pointeur n'est vraiment qu'une adresse.

    Par contre, tu as certainement une documentation te disant quelle taille est autorisée.

  9. #9
    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
    Ce que tu espères faire est strictement impossible.
    Une telle méthode doit obligatoirement savoir la taille maximale. Tu as parlé d'un char[1000] plus haut.. qu'en est-il ?

    de deux choses l'une
    - tu dois allouer str et t'en charges
    -> nécessitera sans doute l'ajout d'une fonction de libération
    - tu dois utiliser str, et il te faut la taille maximale possible

    Y'a pas de magie, et c'est pas par hasard que toutes les méthodes qui utilisent du char* prennent un paramètre supplémentaire pour connaître leur taille, ou savent la "deviner" à coup de strlen.
    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.

  10. #10
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Il te reste plus qu'à rajouter la précondition suivante : la chaîne ne contient pas de '\0' sauf le dernier caractère comme le propose leternel.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char buf[32];
    for (std::size_t i = 0; i < 32; ++i) { buf[i] = 'a'; }
    buf[31] = '\0';
    f(buf);
    --- --- ---

    Ou alors la taille est dans une constante / variable plus ou moins globale.

  11. #11
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    Changer la signature de la fonction n'est aps possible (pour les raisons evoquées precedement), donc "f(buf, sizeof(buf));" pas possible.

    Mettre une taille en globale c'est possible, mais, comment s'assurer que la taille constante est la même que dans le code JNI, exemple:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // Code JNI
     
    #define SIZE 1000
     
    ...
     
    char str[SIZE]; // str sera fournit à la DLL C++
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Code C++
     
    #define SIZE 1000
     
    void f(char* str)
    {
      string sTemp("Portez ce vieux whisky au juge blond qui fume");
      strncpy(str, SIZE sTemp);
    }
    Donc là OK, mais le problème risque de se corser si des modifs sont faites dans le JNI (j'ai pas la main dessus) tout en continuant d'utiliser la DLL (sans synchroniser les changements):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // JNI
    #define SIZE 500
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    // C++
    #define SIZE 1000
     
    void f(char* str)
    {
      string sTemp("Portez ce vieux whisky au juge blond qui fume ......... etc"); // chaine de 800 char par exemple
      strncpy(str, SIZE sTemp);
    }
    Là on aura un soucis d'overflow!

  12. #12
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Tu peux ajouter une fonction dans la dll ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::size_t f_c_str_size() { return 32; }

  13. #13
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    Je pourrais àjouter une fonction usage "interne" de la DLL, mais celle que tu me propose présume que je connaise la taille du tableau, or c'est ce que je cherche à determiner.

    Donc si tu as une fonction du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::size_t getSizeArray(char* array);// array chaine non-initilaisée et probablement vide
    mon problème serait resolu.

  14. #14
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Citation Envoyé par LinuxUser Voir le message
    Je pourrais àjouter une fonction usage "interne" de la DLL, mais celle que tu me propose présume que je connaise la taille du tableau, or c'est ce que je cherche à determiner.
    Je propose une fonction (qui pourrait juste être une variable globale constante) qui retourne une taille arbitraire et qui "force" (faut écrire ça dans la documentation) la taille du char*.

    Si tu veux que la taille du char* puissent varier, il te faut une variable globale non constante qui devra être mise à jour avant l'appel de la fonction (non thread-safe).

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

Discussions similaires

  1. [RegEx] Récupérer les arguments d'une fonction
    Par brunoperel dans le forum Langage
    Réponses: 2
    Dernier message: 29/07/2008, 19h46
  2. Réponses: 7
    Dernier message: 22/06/2008, 00h05
  3. récupérer le nombre d'arguments d'une fonction
    Par hector2 dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 17/03/2008, 11h35
  4. Réponses: 7
    Dernier message: 21/01/2008, 15h17
  5. Réponses: 4
    Dernier message: 05/10/2005, 18h19

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