_M_ construire null non valide erreur lorsque vous essayez de mettre en œuvre multi threaded file d'attente

Je suis en train de mettre en œuvre une file d'attente de priorité à l'aide à l'aide d'une simple approche linéaire, comme expliqué dans L'Art de la programmation Multiprocesseur. Je suis novice en c++ et ont de la difficulté à le dépannage.

J'ai mis en place deux classes de modèle et de suis de les tester à l'aide d'une simple méthode de test. Comme je ne suis pas en mesure de cerner le point de l'erreur, je suis collage de tous les trois classes ci-dessous pour référence.

Je sais que _M_ construct null not valid vient quand on tente de construire une chaîne à l'aide de nullptr, mais je ne suis pas sûr de l'endroit où je fais.

Les trois classes créées sont donnés ci-dessous:

bin.h

#include <mutex>
#include <deque>
#include <memory>
#include <iostream>
using namespace std;

namespace priority
{
    template<typename T>
    class Bin
    {
    private:
        std::deque<T> v;
        std::mutex m;
    public:
        Bin() {
        }

        Bin(const Bin &o) {

        }

        const Bin &operator=(const Bin &other) {
            return *this;
        }

        void put(T item) {
            std::lock_guard<std::mutex> lock(m);
            v.push_back(item);
        }

        T *get() {
            std::lock_guard<std::mutex> lock(m);
            if (v.size() == 0) {
                return nullptr;
            }
            else {
                T val = v.front();
                T *ptr_val = &(val);
                v.pop_front();
                return ptr_val;
            }
        }

        bool isEmpty() {
            std::lock_guard<std::mutex> lock(m);
            return v.size() == 0;
        }

    };  
}

SimpleLinear.h

#include <mutex>
#include <vector>
#include <memory>
#include "Bin.h"

namespace priority
{   
    template<typename T>
    class SimpleLinear
    {
    private:
        int range;
        std::vector<Bin<T>> pqueue;
    public:
        SimpleLinear(int range){
            this->range = range;

            for (int i = 0; i < range; i++)
            {
                pqueue.push_back(Bin<T>());
            }

        }

        void add(T item, int key) {
            pqueue[key].put(item);
        }

        T removeMin() {
            for (int i = 0; i < range; i++)
            {
                T *item = pqueue[i].get();
                if (item != nullptr) {
                    return *item;
                }
            }
            return nullptr;
        }

    };
}

test.cpp

#include <iostream>
#include <vector>
#include <thread>
#include <algorithm>
#include "SimpleLinear.h"
using namespace std;
using namespace priority;

void te(SimpleLinear<string> s, int thread_id) {

    s.add("sundar"+to_string(thread_id), thread_id);
    s.add("akshaya"+to_string(thread_id), 3);
    s.add("anirudh"+to_string(thread_id), 1);
    s.add("aaditya"+to_string(thread_id), 5);
    cout << s.removeMin() << endl;
    cout << s.removeMin() << endl;
    cout << s.removeMin() << endl;

}


int main(int argc, char const *argv[])
{   

    SimpleLinear<string> s(100);
    std::vector<std::thread> v;

    for (int i = 0; i < 100; i++)
    {   
        //if (i % 2 == 0)
            v.push_back(thread(te, std::ref(s), i));
        //else
            //v.push_back(thread(t, std::ref(s), i));


    }
    for_each(v.begin(), v.end(), std::mem_fn(&std::thread::join));
    return 0;
}

J'obtiens le message d'erreur:

terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_M_construct null not valid
terminate called recursively
terminate called recursively
terminate called recursively
Aborted (core dumped)
  • Si vous souhaitez créer une chaîne vide, il suffit de faire par exemple std::string(). Ou pour un type générique T ne T().
  • removeMin est de retour nullptr. Changer de return T();
  • Votre problème est que vous en pensez (je suppose) nullptr signifie "sans objet". C'est faux, nullptr signifie simplement "pointeur null". En C++ (contrairement à des langages comme C# et Java) il n'y a pas une telle chose comme "sans objet".
  • en fait.. je suis vraiment désolé de ce code.. je 'ai posté dans le mauvais code... je l'ai mis à jour
  • SimpleLinear n'est pas thread-safe - vous êtes en train d'ajouter des articles à partir de plusieurs threads dans un std::vector sans verrouillage
  • En linéaire simple, je suis juste l'appel de la mettre de la Corbeille de droit qui est thread-safe, donc dois-je verrouiller il ainsi?
  • pqueue[key].put(item); est un appel à mettre sur pqueue. pqueue n'est pas thread-safe. Bin n'a pas besoin d'être thread-safe, vous n'avez pas plusieurs threads tentent de lecture/écriture à une instance en même temps
  • Maintenant, après votre montage, vous avez un comportement indéfini au lieu de cela, comme vous le retour des pointeurs vers des variables locales. Ne pas mise à jour de votre question pour "réparer" le code. Que tirer le tapis sous nos pieds, pour ainsi dire. Elle permet à nos commentaires et les réponses possibles de mal.

InformationsquelleAutor anirudh | 2016-11-18