Я пытаюсь создать очередь с минимальным приоритетом, одна из проблем, с которыми я сталкиваюсь, заключается в том, что я не могу понять, как инициализировать значение параметров, которые я ввожу в командной строке... Я получаю ошибку seg, когда пытаюсь для ввода значений.
Я чувствую, что упускаю что-то очень очевидное, но я на пределе своих возможностей, пытаясь понять это. Любая помощь приветствуется, так как я новичок в кодировании в целом. Спасибо..
//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;
}
string* id;
Почему вы храните здесь указатель на строку? Это, вероятно, причина, почему ваша программа терпит неудачу.
мой учитель хотел, чтобы мы так делали, я тоже думал, что это странно.
«мой учитель хотел, чтобы мы сделали это таким образом». Мне очень трудно поверить... Он упоминал что-нибудь о const char *
? Удалите указатель из строки, и код работает нормально.
@ConstantinosGlynos нет, она дала нам файл .h и названия функций
Что ж, в этом случае причина, по которой ваш код не работает, заключается в том, что вы пытаетесь присвоить значение этому указателю с помощью разыменования *id = " "
или *id = i
, когда id
не имеет выделенной памяти, что означает, что его нельзя разыменовать. Есть несколько способов «исправить» вашу программу.
Примечание. Имена, начинающиеся с подчеркивания, за которым следует заглавная буква, и имена, содержащие двойное подчеркивание в любом месте, являются зарезервировано для реализации, и вам не разрешается создавать такие имена самостоятельно. Ваше защитное имя заголовка __MinPriorityQueue
не соответствует этим правилам.
Причина, по которой ваш код не работает, заключается в том, что вы пытаетесь присвоить значение указателю std::string *id
посредством разыменования *id = " "
и *id = i
, когда указатель id
не имеет выделенной памяти. Это означает, что его нельзя разыменовать.
Есть несколько способов «исправить» вашу программу.
Опция 1: Сделать std::string *id
константой и присвоить адрес переменной 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;
.
Надеюсь это поможет.
Почему вы сделали член
id
указателем?