I'm currently writing a code to manipulate linked lists. For that I created the struct Node with a value of type const int and a pointer to the next element and a class Queue, that includes a pointer to the first and a pointer to the last element of the list.
Now I've run into a problem when trying to delete the first element of the queue and return the value of that element. Somehow the function is only deleting the first time i use it correctly and then jumping to either some random other element or directly to the last element.
This is my code so far:
1 2 3 4 5 6 7 8 9 10 11 12
int Queue::dequeue() {
Node*t = new Node{first->value, first};
if(first == nullptr)
return 0;
else{
t = first;
first = first -> next;
}
return t -> value;
}
Why is first being passed as a param to Node? Why are you creating a new Node to delete the first element? The memory allocated to t isn't freed so there is a memory leak. When do you free the memory used by the first element? Don't you need something like (not tried):
1 2 3 4 5 6 7 8 9 10 11
int Queue::dequeue() {
if (first == nullptr)
return 0;
constauto f{ first };
constauto v{ f->value };
first = first->next;
delete f;
return v;
}
So you're creating a node that is equal to first and a value that is equal to the value of first?
That was what i was trying to do actually. I just didn't know how to initialize Node t. Let me try your suggestion...
Okay, so now there is no "Invalid Read" - Error anymore, but given the list with the following values: 23 -1 -4. I want to dequeue the first two, so 23 and -1. But the code deletes 23 and -4. Why?
struct Node {
Node(constint _value, Node* _next) : value(_value), next(_next) { }
constint value;
Node* next;
};
class Queue {
public:
// PRE: -
// POST: Valid and empty queue.
Queue();
// PRE: Valid queue.
// POST: Valid queue with new node having value i added at end of queue.
void enqueue(int value);
// PRE: Valid and non-empty queue.
// POST: Removes first node from queue.
// Returns content of first node.
int dequeue();
// PRE: Valid queue.
// POST: Returns true if queue is empty, false otherwise.
bool is_empty() const;
// PRE: Valid queue.
// POST: Outputs queue content to os in sequence from first to last.
void print(std::ostream& os) const;
// PRE: Valid queue
// POST: Outputs queue content to os in reverse order, from last to first.
void print_reverse(std::ostream& os) const;
private:
// Class invariant: first == nullptr iff last == nullptr
Node* first; // pointer to first element of queue or nullptr is queue is empty.
Node* last; // pointer to last element of queue or nullptr if queue is empty.
// PRE: -
// POST: Ensures class invariant.
void is_valid() const;
};
#endif
int main() {
Queue q;
// parse and process the test data until the end marker occurs.
// The format of the test data is:
// <function> <parameter>
// where <parameter> is optional and specific to the function.
while (std::cin.good()) {
// get <function>, exit if end marker occurs
std::string function;
std::cin >> function;
if (function == "end") {
break;
}
if (function == "dequeue") {
std::cout << q.dequeue() << "\n";
} elseif (function == "enqueue") {
int value; // parameter "value"
std::cin >> value;
q.enqueue(value);
} elseif (function == "is_empty") {
std::cout << q.is_empty() << "\n";
} elseif (function == "print_reverse") {
q.print_reverse(std::cout);
std::cout << "\n";
} else {
std::cout << "unknown function: " << function << "\n";
break;
}
}
return 0;
}