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 :

Pointeur sur std::vector casser après un resize()


Sujet :

Langage C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 63
    Points : 42
    Points
    42
    Par défaut Pointeur sur std::vector casser après un resize()
    Bonjour à tous.

    J'ai un petit souci avec mon vector.

    Petite explication sur le fonctionnement de mon application :

    Chaque ligne contiens une structure et j'utilise un pointeur vers celle si depuis des threads.

    Avant chaque création de thread je fais un resize() a fin d'ajouter une ligne et d’incorporer une structure.

    Le problème est qu’à chaque resize() cela doit modifier l'emplacement mémoire des précédentes lignes et cela casse donc les pointeurs de mes précédents threads.


    Quelqu'un aurais une idée de comment contourner ce problème?

    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
    /* .... */
            std::vector< thread_data> vectorTelechargement;
     
    /* .... */
     
            pthread_t threads;
            int sizeVec = vectorTelechargement.size();
     
            vectorTelechargement.resize(sizeVec+1);
            vectorTelechargement[sizeVec].statusDownload = true;
            vectorTelechargement[sizeVec].nbThread = 1;
            vectorTelechargement[sizeVec].URL = URL.toStdString();
            vectorTelechargement[sizeVec].hDlg = (QMainWindow * )ui->pushButtonDownload->parent();
            vectorTelechargement[sizeVec].tableViewDownload = (QTableView *)ui->tableViewDownload;
            vectorTelechargement[sizeVec].modelTableView = (QStandardItemModel *)model;
     
            pthread_create(&threads, NULL, EnvoieDL, (void *)&vectorTelechargement[sizeVec]);

  2. #2
    Membre éclairé
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Points : 879
    Points
    879
    Par défaut
    En effet, resize() casse les pointeurs. Au passage, c'est particulièrement horrible d'utiliser de tels pointeurs ; et un push_back() serait tellement plus joli ...

    La solution est alors de passer à la fois un pointeur vers le vector lui-même (qui, lui, ne sera pas affecté par le push_back()), et l'index de l'objet.

    Quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    struct element {
        std::vector<thread_data>* data;
        std::size_t index;
        thread_data & get() {
            return (*data).at(index);
        }
    };
     
    // Utilisation :
    element e(&v, i); // Créée un élément e du vecteur v à l'index i
    e.get(); // Retourne une référence vers l'élément pointé par e

  3. #3
    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
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    A chaque resize, si besoin, le vecteur réalloue de l'espace mémoire. D'où le changement d'adresse de tes objets.
    => Utilise un index plutôt qu'un pointeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    /* .... */
            std::vector< thread_data> vectorTelechargement;
     
    /* .... */
     
            pthread_t threads;
            pthread_create(&threads, NULL, EnvoieDL, (void *)sizeVec);
    => ou utilise une list qui n'invalide pas les itérateurs existants lors des ajouts/suppressions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    /* .... */
            std::list< thread_data> vectorTelechargement;
     
    /* .... */
     
            pthread_t threads;
            pthread_create(&threads, NULL, EnvoieDL, (void *)vectorTelechargement.back());

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 63
    Points : 42
    Points
    42
    Par défaut
    Merci pour vos réponses.

    J'ai donc essayé un peu tous ce que vous m'avez proposé, je n'arrive vraiment pas à faire passer le vecteur lui-même avec un index. Je me retrouve sans le contenue du vecteur( plus précisément un vector d’une taille énorme sans contenue , et un index différent de celui spécifier.

    Concernant le std::list cela marche parfaitement il y a juste un seul problème, je peux modifier la ligne de la std::list fournis au thread , depuis le thread même.

    Je ne peux par contre pas le modifier depuis la partit qui lance la thread.

    Je suis en train de faire une fonction Play / Stop car les thread télécharge des fichier c'est pour cela que j'ai besoin de pouvoir communiquer via l'intermédiaire d'une structure différente pour chacun.

    Comment je peux modifier ce contenue car j'ai regardé partout sur le net, je n'ai rien trouver concernant le changement du contenue d'un std::list ?

    Concernant le fonctionnement de mon application voici un petit shéma :

    Quand on ajoute un téléchargement :

    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
     */
            std::vector< thread_data> vectorTelechargement;
     
    /* .... */
     
            pthread_t threads;
            int sizeVec = vectorTelechargement.size();
     
            vectorTelechargement.resize(sizeVec+1);
            vectorTelechargement[sizeVec].statusDownload = true;
            vectorTelechargement[sizeVec].nbThread = 1;
            vectorTelechargement[sizeVec].URL = URL.toStdString();
            vectorTelechargement[sizeVec].hDlg = (QMainWindow * )ui->pushButtonDownload->parent();
            vectorTelechargement[sizeVec].tableViewDownload = (QTableView *)ui->tableViewDownload;
            vectorTelechargement[sizeVec].modelTableView = (QStandardItemModel *)model;
     
            pthread_create(&threads, NULL, EnvoieDL, (void *)&vectorTelechargement[sizeVec]);

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void* EnvoieDL(void* data) // Thread D'envoie a la classe
    {
        thread_data *my_data;
        my_data = (thread_data*) data;
     
        Downloader down;
        down.downloadFile(my_data);
     
        pthread_exit(NULL);
        return NULL;
    }

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    Downloader::downloadFile(thread_data* info)
    {
    /* ...... */
     std::vector<CdownloadThread> vec;
     
        info->distFile = Downloader::distFile;
        info->file = Downloader::file;
        info->hebergeur = Downloader::hebergeur;
        info->localFile = Downloader::file;
        info->downloaded = 0;
        info->lastDownloaded = 0;
        info->erreur = 0;
     
    /* ...... */
     
     pthread_t *threads;
            threads = (pthread_t*) malloc( sizeof(pthread_t) * info->nbThread );
     
            // taille a DL par thread
            int quant = info->lengthFile / info->nbThread;
     
     
            // Configure et lance chaque thread ( 6 par défaut)
            vec.resize(info->nbThread);
            int x= -1;
            for(int i = 0 ; i < info->nbThread ; i++)
            {
                if( i == (info->nbThread - 1))
                {
                    vec[i].idThread = i;
                    vec[i].startPoint= x + 1;
                    vec[i].quant = 0;
                    vec[i].backptr = info;
                }
                else
                {
                    vec[i].idThread = i;
                    vec[i].startPoint= x + 1;
                    vec[i].quant = x + quant;
                    vec[i].backptr = info;
                }
                x += quant;
                pthread_create(&threads[i], NULL, DownloadThread, (void *)&vec[i]);
     
            }
     
            for(int i = 0 ; i < info->nbThread ; i++)
            {
                pthread_join(threads[i], NULL);
            }
     
    /* ...... */
     
    }

Discussions similaires

  1. pointeur sur un vector de template
    Par Shibron dans le forum Langage
    Réponses: 5
    Dernier message: 29/04/2011, 15h33
  2. Question sur std::vector
    Par FabaCoeur dans le forum SL & STL
    Réponses: 11
    Dernier message: 24/06/2007, 18h22
  3. tri sur std::vector<std::pair<int, float> >
    Par b4u dans le forum SL & STL
    Réponses: 15
    Dernier message: 01/10/2006, 09h19
  4. std::sort() sur std::vector()
    Par tut dans le forum SL & STL
    Réponses: 20
    Dernier message: 05/01/2005, 19h15
  5. vector de pointeurs sur des objet
    Par jean-bobby dans le forum SL & STL
    Réponses: 26
    Dernier message: 06/08/2004, 14h54

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