Как правильно получить доступ к значению параметра, который передается по ссылке на конструктор из стандартного ввода? - PullRequest
0 голосов
/ 07 апреля 2019

Я пытаюсь создать очередь с минимальным приоритетом, одна из проблем, с которыми я сталкиваюсь, заключается в том, что я не могу понять, как инициализировать значение параметров, вводимых в командной строке ... Я получаю ошибку сегментакогда я пытаюсь ввести значения.

Я чувствую, что упускаю что-то очень очевидное, но я в конце концов пытаюсь понять это.Любая помощь очень ценится, так как я довольно новичок в кодировании в целом.Спасибо ..

    //header file 
   #ifndef __MinPriorityQueue
   #define __MinPriorityQueue

   #include <string>
   #include <list>
   #include <vector>

   using std::vector;
   using std::string;
   using std::list;

class MinPriorityQueue{

    public:
        MinPriorityQueue();                       //constructor
        ~MinPriorityQueue();                      //destructor
        void insert(const string&, int key);      //insert string and key
        void decreaseKey(const string id, int newKey);  //decreases key in minqueu
        string extractMin();                      //extracts the min string

    private:
        void buildMinHeap();     //produces a min heap from an unordered array
        void minHeapify(int i);  //maintain the min-heap property
        int parent(int i);       //returns min value 
        int left(int i);         //returns smaller val
        int right(int i);        //returns larger val

        class Element
        {
            public:
                Element();
                Element(const string& id, int key);
                ~Element();
            private:
                string* id;
                int key;
        };
        vector<Element*>minheap;
};

#endif

//. Cpp файл

MinPriorityQueue::Element::Element()
{
    *id="";
    key=0;
}
MinPriorityQueue::Element::Element(const string& i, int k )
{
    *id=i;//segfaults here
    key=k;
}

// main.cpp

#include "minpriority.h"
#include <iostream>

using std::cout;
using std::cin;
using std::endl;

int main(){
    char command='w';
    cin>> command;
    MinPriorityQueue minQue;
    while(command!='q'){
        if (command== 'a')
        {
            string id;
            int key;
            cin>>id>>key;
            minQue.insert(id, key);
        }
        else if (command== 'd')
        {
            string id;
            int key;
            cin>>id>>key;
            minQue.decreaseKey(id, key);
        }
        else if (command== 'x')
        {
            cout<<minQue.extractMin()<<endl;
        }
        cin>>command;
    }
    return 0;
}

1 Ответ

1 голос
/ 07 апреля 2019

Причина, по которой ваш код не работает, заключается в том, что вы пытаетесь присвоить значение указателю std::string *id путем разыменования *id = " " и *id = i, когда указателю id не выделена память.Это означает, что его нельзя разыменовать.

Существует несколько способов «исправить» вашу программу.

Опция 1: Сделать std::string *id const и назначить адреспеременная user_id из main.

class MinPriorityQueue
{
    private:
        class Element
        {
            private:
                const std::string *id;
                int key;

            public:
                Element(const std::string &i, int k)
                {
                    id = &i;
                    key = k;
                }
                ~Element() = default;
        };
        std::vector<Element*> minheap;

    public:
        void insert(const std::string &s, int k)
        {
            minheap.push_back(new Element(s,k));
        }
};

int main()
{
    MinPriorityQueue minQue;

    std::string user_id = "test";
    minQue.insert(user_id, 2);
}

Опция 2: Выделить память для std::string *id.

class MinPriorityQueue
{
    private:
        class Element
        {
            private:
                std::string *id;
                int key;

            public:
                Element(const std::string &i, int k)
                {
                    id = new std::string(i);
                    key = k;
                }
                ~Element() = default;
        };
        std::vector<Element*> minheap;

    public:
        void insert(const std::string &s, int k)
        {
            minheap.push_back(new Element(s,k));
        }
};

int main()
{
    MinPriorityQueue minQue;

    minQue.insert("test", 2);
}

Опция 3: Удалите const из параметров функции, чтобы его 'адрес мог быть назначен неконстантному указателю члена.

class MinPriorityQueue
{
    private:
        class Element
        {
            private:
                std::string *id;
                int key;

            public:
                Element(std::string &i, int k)
                {
                    id = &i;
                    key = k;
                }
                ~Element() = default;
        };
        std::vector<Element*> minheap;

    public:
        void insert(std::string &s, int k)
        {
            minheap.push_back(new Element(s,k));
        }
};

int main()
{
    MinPriorityQueue minQue;

    std::string user_id = "test";
    minQue.insert(user_id, 2);
}

Опция 4 (и мой личный фаворит): Преобразовать указатель std::string *id; в обычную строку std::string id;.

пс.При использовании метода указателя ваш конструктор по умолчанию должен либо выделить память и инициализировать строку пустой строкой std::string *id = new std::string("");, либо определить ее как нулевой указатель std::string *id = nullptr;.

Надеюсь, это поможет.

...