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 :

Initialisation et allocation vector par son constructeur


Sujet :

C++

  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 Initialisation et allocation vector par son constructeur
    Bonjour,

    J'ai un soucis avec l'allocation d'un vector.

    En fait, je n'arrive pas à comprendre pourquoi les exemples suivants ne sont pas équivalents:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //Exemple 1:
     
    std::vector<double> v1;
    v1.reserve(5); // edit: v1.resize(5);
    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(3);
    v1.push_back(4);
    v1.push_back(5);
     
    std::vector<double> v2 = std::vector<double>(v1.size(), 0.0);
    v2[v2.size()-1] = 3.14; // !!! seg fault
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //Exemple 2:
     
    std::vector<double> v1;
    v1.reserve(5); // edit: v1.resize(5);
    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(3);
    v1.push_back(4);
    v1.push_back(5);
     
    std::vector<double> v2;
    v2.resize(v1.size, 0.0);
    v2[v2.size()-1] = 3.14; // OK
    Sachant que dans l'Exemple 1 on aura une seg fault (out of range) si on veut accéder au dernier élément du vector (à savoir v2[4]) et pas dans l'Exemple 2.
    Pourtant, je vérifie les caractéristiques du vector v2 qui indiquent: size =5 et capacity = 5.

    Je ne comprends absolument pas pourquoi.

  2. #2
    Membre expérimenté Avatar de RPGamer
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Mars 2010
    Messages
    168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués

    Informations forums :
    Inscription : Mars 2010
    Messages : 168
    Par défaut
    Salut,

    moi je vois pas de problème dans ton premier code et il s'exécute parfaitement chez moi. Quel compilateur est-ce que tu utilise et avec quelles options activées ?
    En revanche dans ton 2ème code il manque des parenthèses, il ne compile pas.

  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
    Salut,

    Il s'agit de Visual C++ (VS 2010).

    Pour être plus précis je mix du C# et du C++ en passant par un wrapper C++/CLI.

    Le vector "v1" est alloué dans le wrapper CLI puis passé par référence au code C++ qui l'utilise pour initialiser le vector "v2".

    En faisant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector<double> v2 = std::vector<double>(v1.size(), 0.0);
    Si ensuite je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(i=0; i < v2.size(); i++)
    {
      v2[i] = .... ;
    }
    Cela va marcher jusque v2.[v2.size()-2] et planter pour v2[v2.size()-1];
    Incompréhensible

  4. #4
    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 : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Juste comme ça : avec un resize(5) suivi de 5 push_back, ton vector contient 10 éléments et non 5.
    Quand ça crash, qu'indique le debugger ? Quelle est la véritable size de v1 ? Et celle de v2 ? As-tu essayé avec une ranged-for loop ?
    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.

  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
    Pardon, je voulais écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    v1.reserve(5); // au lieu de v1.resize(5);
    Le debug de VS 2010 crash avec un "out of range" alors que juste avant de crasher j'affiche "size" et "capacity" dans le debugguer et elles valent toutes les deux 5 (idem pour v1 et v2).

  6. #6
    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 : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Mué, je reste sceptique. Ton problème doit forcément venir d'ailleurs. Comme comment fais-tu ton "transfert de C# vers C++" ? Regarde plutôt du côté de ton wrapper dont on ne sait rien pour le réel problème.
    Parce qu'en C++ seulement, le code que tu montres n'as absolument aucune chance de planter, sauf à faire n'importe quoi avec plusieurs threads qui modifient v2. Ou d'avoir bidouiller la stl n'importe comment.
    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.

  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
    Du côté wrapper, cela ressemble à:

    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::vector<double> Wrapper::ListToVector(List<double>^ list)
    	{
    		std::vector<double> result;
     
    		if (list == nullptr) 
    		{
    			throw gcnew ArgumentNullException(L"list");
    		}
    		else
    		{
    			result.reserve(list->Count);
    			for each (double elem in list)
    			{
    				result.push_back(elem);
    			}
    		}
     
    		return result;
    	}
    /*----------------------------------------------------------------------------*/
    void Wrapper::callNativeCode(List<double>^ list)
    {
      Native object = Native();
      std::vector<double> v1 = ListToVector(list);
     
      object.calculation(v1);
     
     
    }
    Du côté code C++ de calculs:
    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
    void Native::calculation(const std::vector<double>& v1)
    {
      unsigned int i = 0;
      // plante dans la boucle for (out of range)
      //std::vector<double> v2= std::vector<double>(v1.size(), 0.0);
      // ne plante pas
      std::vector<double> v2;
      v2.resize(v1.size(), 0.0);
      // plante à la dernière itération
      for(i=0; i < v2.size(); i++)
      {
         v2[i] = 3.14;
      }
     
    }

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    C'est bizarre, je ne vois aucune erreur dans ton code C++/CLI...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 467
    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 467
    Par défaut
    Y a un truc que je ne comprends pas, c'est comment avoir une liste .NET de "double" natif ?
    Vous êtes sûr qu'on a le même type de double en entré et en sortie ???

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Oui, à ma connaissance System::Double et le double natif sont traités comme exactement le même type par le Common Type System.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Réponses: 9
    Dernier message: 31/07/2006, 21h19
  2. [DLL] Acces a une methode par son index de maniere dynamique
    Par Clorish dans le forum API, COM et SDKs
    Réponses: 2
    Dernier message: 11/03/2005, 17h14
  3. Accéder à un serveur linux par son nom
    Par flatron dans le forum Réseau
    Réponses: 6
    Dernier message: 01/07/2004, 14h27
  4. Réponses: 4
    Dernier message: 06/06/2004, 12h07
  5. Réponses: 2
    Dernier message: 10/05/2004, 11h20

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