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

SL & STL C++ Discussion :

Assigner un tableau C à un std::vector


Sujet :

SL & STL C++

  1. #1
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Par défaut Assigner un tableau C à un std::vector
    Bonjour,
    je suis sur un projet C++ dans lequel je suis - pour résumer - contraint d'utiliser des données à partir d'un tableau C classique (1024 éléments de type double).
    J'aimerais "encapsuler" ce tableau avec un std::vector pour rendre son utilisation plus commode, c'est à dire créer un vector<double> de taille 1024 qui manipulerait cette plage de données sans avoir à la recopier ailleurs en mémoire.

    Comment dois-je procéder ?
    Merci.

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour,
    A mon sens, il n'existe rien de standard avec std::vector pour faire ça. Normalement, le std::vector a la responsabilité de gérer la façon dont il maintient les données.
    Ensuite, avec une implémentation particulière, il y aurait certainement moyen de bidouiller avec un allocateur maison qui retournerait ta zone mémoire. Mais je pense que ce sera une origine de bugs inutile.
    Donc, le meilleur conseil est encore la recopie ou l'encapsulation de ton tableau dans ta structure idoine. Que te manque-t-il pour ne pas utiliser directement ton tableau ? Tu peux appliquer les algos sur un tableau. Ca ne pose pas de problème...

  3. #3
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 641
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 641
    Par défaut
    Salut,

    Déjà, je me demande pourquoi manipuler un tableau C style au lieu d'un std::vector...

    Après tout, si tu sais pertinemment le nombre d'éléments que ton tableau va devoir contenir, tu pourrais tout à fait travailler, au choix:
    • Avec un std::vector et sa fonction reserve
    • Avec un boost::array qui est un tableau de taille fixe "stl Like"

    Comme il s'agit de tableaux contigus en mémoire, si tu as, à un moment donné, réellement besoin d'un pointeur sur le premier élément (par exemple pour le passer en paramètre à une fonction écrite en C), tu peux toujours prendre... l'adresse de l'élément se trouvant en indice 0

    Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    std::vector<double> tab;
    tab.reserve(1024);
    double* = &tab[0]; // je t'assure, ca marche :D
    Tant que tu ne tentera pas d'accéder à d'autres éléments qu'aux 1024 réservés, tu n'aura strictement aucun problème
    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

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Tant que tu ne tentera pas d'accéder à d'autres éléments qu'aux 1024 réservés, tu n'aura strictement aucun problème
    En revanche, reserve ne fait pas augmenter le nombre d'élément du vecteur. Il faut pour cela utiliser resize.

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 641
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 641
    Par défaut
    oupppss... au temps pour moi
    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
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Par défaut
    Pour être plus précis, j'utilise une bibliothèque semblable à boost::uBlas (nt2) pour des calculs matriciels. Celle-ci utilise ses propres conteneurs génériques pour effectuer ses calculs. Ces conteneurs garantissent entre autre que les données d'une matrice appartiendront toujours à une zone mémoire contigüe. Comme il m'est possible d'obtenir l'adresse du premier élément de ce conteneur, je peux donc (si je le souhaite) créer un tableau C pour accéder à n'importe quel élément de la matrice.

    Il se trouve que j'ai besoin de convertir ce conteneur nt2 en un std::vector pour les raisons citées dans mon premier post. Donc mon problème me semble bien être " Comment créer un std::vector à partir d'un tableau C déjà alloué ? "...

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par cob59 Voir le message
    Pour être plus précis, j'utilise une bibliothèque semblable à boost::uBlas (nt2) pour des calculs matriciels. Celle-ci utilise ses propres conteneurs génériques pour effectuer ses calculs. Ces conteneurs garantissent entre autre que les données d'une matrice appartiendront toujours à une zone mémoire contigüe. Comme il m'est possible d'obtenir l'adresse du premier élément de ce conteneur, je peux donc (si je le souhaite) créer un tableau C pour accéder à n'importe quel élément de la matrice.

    Il se trouve que j'ai besoin de convertir ce conteneur nt2 en un std::vector pour les raisons citées dans mon premier post. Donc mon problème me semble bien être " Comment créer un std::vector à partir d'un tableau C déjà alloué ? "...
    Que ferais-tu de plus avec un std::vector que tu ne fais pas avec ton pointeur ?

  8. #8
    Membre expérimenté Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Par défaut
    Si c'est pour être sur que la mémoire soit désallouée, il est possible de placer ce double* dans un boost::scoped_array, ou boost::shared_array.

  9. #9
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Je plussois tout ce qui a été dit.

    Mais s'il faut ab-so-lu-ment encapsuler le contenu d'un pointeur dans un std::vector sans faire aucune recopie, alors il faut passer par l'écriture d'un allocator.

  10. #10
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Par défaut
    Que ferais-tu de plus avec un std::vector que tu ne fais pas avec ton pointeur ?
    Tu me demandes l'intérêt d'un std::vector par rapport à un tableau C ?



    Bon, je UP ce topic parce qu'en cherchant des infos sur le constructeur de std::vector je suis tombé là-dessus : http://www.cplusplus.com/reference/stl/vector/vector/

    En gros il semble qu'on puisse faire la chose suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    // Exemple de création d'un pointeur vers des données, mais dans mon
    // cas il vient d'une fonction tierce
    double* pMatrice = { 20.0, 1.3, 4.9, 2.2 };
    size_t tailleMatrice = 4;
     
    // Le std::vector est construit avec les deux pointeurs début/fin de la matrice
    // L'objet n'efface pas (a priori) les données lors de sa destruction
    std::vector<double> vMatrice(pMatrice, pMatrice + tailleMatrice);
    Ce serait aussi simple que ça ?

  11. #11
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Citation Envoyé par cob59 Voir le message
    Ce serait aussi simple que ça ?
    Non. Ce constructeur fait une copie du tableau contenu entre les deux pointeurs.

    Ce n'est pas la peine de chercher des feintes, il n'existe aucun moyen de forcer un vecteur à utiliser ton propre buffer sans passer par une copie. Car fondamentalement un std::vector est autorisé à faire ce qu'il veut avec la mémoire qu'il possède (par exemple réallouer un nouveau bloc et dégager l'ancien), donc il n'y aurait aucune garantie que ton buffer s'en sorte vivant.

    Il existe peut être une exception, comme l'a indiqué camboui, c'est d'implémenter son propre allocateur.
    Et justement, une proposition est recemment passée sur la mailing list de boost, boost::monotonic, pour avoir des conteneurs auquel on pourrait passer son propre buffer (avec plein de restriction). Au vu du débat provoqué, ça a l'air extremement casse-gueule à faire, voire impossible

Discussions similaires

  1. Réponses: 11
    Dernier message: 28/12/2011, 10h19
  2. std::sort() sur std::vector()
    Par tut dans le forum SL & STL
    Réponses: 20
    Dernier message: 05/01/2005, 19h15
  3. char[50] et std::vector<>
    Par tut dans le forum SL & STL
    Réponses: 9
    Dernier message: 12/10/2004, 13h26
  4. Réponses: 8
    Dernier message: 26/08/2004, 18h59
  5. Sauvegarde std::vector dans un .ini
    Par mick74 dans le forum MFC
    Réponses: 2
    Dernier message: 12/05/2004, 13h30

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