Sort() leads to Segmentation Fault - c++

I have to implement a shuffleString(string s,int d) method where the first step involves getting the count of each character in the string and arranging them in the decreasing order of their count. I implemented the required functionality as follows:
struct node{
char ch;
int ctr;
};
bool myfunc(const struct node x,const struct node y){
return (x.ctr>=y.ctr?true:false);
}
string shuffleString(string s,int d){
int i,j;
int len=s.size();
vector<struct node> counter(26);
for(i=0;i<26;i++){
counter[i].ch='a'+i;
counter[i].ctr=0;
}
for(i=0;i<len;i++){
counter[s[i]-'a'].ctr++;
}
sort(counter.begin(),counter.end(),myfunc);//From STL's algorithm
/*
Remaining Functionality
*/
}
However, the code generates a segmentation fault when the sort() method is called. What is wrong with my code? Please help.
P.S. The string only contains lowercase ASCII characters.

try this
bool myfunc(const struct node x,const struct node y){
return (x.ctr>y.ctr) || (x.ctr == y.ctr && x.ch < y.ch);
}
EDITED:
you should handle the break tie case (separate > and == cases instead of >=)
Your algorithm will fail when input has any char other than a-z (even A-Z)
A small snippet is here:
struct node{
char ch;
int ctr;
};
bool myfunc(const struct node x,const struct node y){
return (x.ctr>y.ctr) || (x.ctr == y.ctr && x.ch < y.ch);
}
void shuffleString(string s){
int i,j;
int len=s.size();
vector<struct node> counter(26);
for(i=0;i<26;i++){
counter[i].ch='a'+i;
counter[i].ctr=0;
}
for(i=0;i<len;i++){
counter[s[i]-'a'].ctr++;
}
for(int i=0; i<26;i++) cout << counter[i].ch <<"," << counter[i].ctr << endl;
cout << endl << endl;
sort(counter.begin(),counter.end(), myfunc);//From STL's algorithm
for(int i=0; i<26;i++) cout << counter[i].ch <<"," << counter[i].ctr << endl;
}
int main()
{
shuffleString("hello");
return 0;
}

You likely have got memory corruption in the line: counter[s[i]-'a'].ctr++;
s[i]-'a' can be more than 25, what is out of the vector boundary.

stl sort uses operator< by default - it expects the function you pass in to behave in the same way.
This means that if it calls the function on two identical values it should get false, but in your case it would get true. Because of this it will not correctly sort.
When you remove the = the function no longer has this issues since operator> is non reflexive like operator <
If you run with the debug c runtime STL will first assert that the passed in function is well formed.

Related

c++ Problem sorting struct array, probably issue with pointers [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 months ago.
Improve this question
I am learning c++. I got a struct array that has an attribute that is also a struct.
typedef struct Date
{
int day, month, year;
}Date;
typedef struct {
int order_num;
Date order_day; //Sort
string client;
string tech_type;
int serial_key;
char problem[50];
string technician_name;
char tech_fix[500];
int price;
int days_spent;
string status;
string order_type;
string urgency;
int problems_num;
faults problems[10];
}tech_info;
The question is that I need to sort it via date, that is the second attribute on tech_info.
Here is my attempt:
bool compare_date(const tech_info *a, const tech_info *b)
{
if (a->order_day.year < b->order_day.year)
return true;
if (a->order_day.year == b->order_day.year &&
a->order_day.month < b->order_day.month)
return true;
if (a->order_day.year == b->order_day.year &&
a->order_day.month == b->order_day.month &&
a->order_day.day < b->order_day.day)
return true;
// If none of the above cases satisfy, return false
return false;
}
static void sort_date(tech_info* all_orders[]) {
sort(all_orders, all_orders + counter, compare_date);
cout << "Sorted by date. " << "\n";
}
In this case counter is the amount of entries the user has submitted.
I submit two entries. For the first one I read the information correctly, but for the second one I don't. I'll attach two screenshots to show. Where is my mistake?
Update: Given that I am accessing bad memory I'll post a bit more of my code, all the parts that have to do with this logic.
Here is where I declare my array:
print_menu_initial();
int user_input;
cin >> user_input;
tech_info* orders[100]; //Empty by default
switch (user_input) {
case 1:
do_work_technician_mode(orders);
break;
case 2:
do_work_customer_mode(orders);
break;
}
Then the user does some operations to add orders from here:
static void do_work_customer_mode(tech_info* all_orders[]) {
while (true) {
cin >> user_input;
switch (user_input) {
case 0:
do_work_technician_mode(all_orders);
break;
case 1:
order[counter] = add_order();
all_orders[counter] = &order[counter];
counter++;
break;
case 2:
cout << "How many orders would you like to add? ";
cin >> many_orders;
for (int i = 0; i < many_orders; i++) {
cout << "Information for next order: " << "\n";
order[counter + i] = add_order();
all_orders[counter + 1] = &order[counter + 1];
}
counter = counter + many_orders;
break;
case 6:
sort_date(all_orders);
break;
}
The other cases are irrelevant, I believe. This is the sorting part. Counter is an int variable, declared 0 at start. Whenever the customer adds new entries I increase the value of counter with the number of entries he adds.
Funny enough - for my screenshot - variable a gets read correctly, just b is not being read correctly.
It appears that you have come to C++ from a C background. That is not a bad thing, but I would recommend learning to use as much of the standard library as you can. C++20 in particular has added many features that make it easier to work with collections of objects. This requires a (somewhat) up to date compiler, but is definitely worth it. Here is how I would prefer to approach a problem like this in C++.
There are two choices: keeping the collection of orders sorted at all times, or sorting only when needed. The former can be achieved using an ordered container such as std::set, the latter is what you are currently doing using std::sort. However, you could make your life a lot easier by storing the orders in a container like std::vector. Adding a new order is then as simple as
orders.emplace_back(add_order());
Tracking the number of orders in a counter variable is not necessary, since the vector has a size() function.
Further, if there is a natural choice of ordering among values of a type, as is the case with dates, then the recommendation in C++ is to overload comparison operators. This allows for uniform expression syntax like a != b and x < y when this makes sense for your class. By carefully ordering the members of your Date struct, this can be achieved with almost no code in modern C++:
#include <compare>
struct Date {
int year, month, day;
friend auto operator<=>(Date const&, Date const&) = default;
};
static_assert(Date{2000, 1, 1} < Date{2000, 1, 2});
A more sophisticated approach would also prohibit the construction of invalid dates. Classes designed this way were introduced to the std::chrono namespace with C++20; you should now be able to use a class like year_month_day that provides what you need out of the box.
Either way, C++20's range-based std::ranges::sort algorithm then allows you to specify both a comparison and a projection function; the projected values are compared to determine the sorting order. Therefore, once you have a date class with comparison operators, you can also sort the orders like this:
#include <algorithm>
auto order_date = [](auto const& order) -> auto& { return order.order_date; };
std::ranges::sort(orders, std::ranges::less{}, order_date);
The answer to your problem was a type in all_orders[counter + i] = &order[counter + i];
But since we're here let me clean your code up a bit. I can see you've most likely come from C as most of your syntax is C like. So here are some rules (some may be controvertial but wtvr
typedef struct Date //for structs -> struct NAME. typedef not needed
{
int day, month, year;
}Date; //you're declaring globabl object which isnt that good you want to have as little variables globally
typedef struct { //same here
int order_num; //struct has a lot of variables, i assume all of them are needed
Date order_day; //Sort
string client;
string tech_type;
int serial_key;
char problem[50]; //if this can have many sizes better use string
string technician_name;
char tech_fix[500]; //same here. string. you can always change string to char using function someStringName.c_str() other way round is also possible with minimal effort
int price;
int days_spent;
string status;
string order_type;
string urgency;
int problems_num;
faults problems[10];
}tech_info; //same here
What you'd prefer to see in a cpp program is the following:
struct Date
{
int day, month, year;
};
struct tech_info{
int order_num;
Date order_day; //Sort
string client;
string tech_type;
int serial_key;
string problem;
string technician_name;
string tech_fix;
int price;
int days_spent;
string status;
string order_type;
string urgency;
int problems_num;
faults problems[10];
};
And then your actual objects created in eg main function or some other function.
Next your sorting:
bool compare_date(const tech_info &a, const tech_info &b) //pointers to references
{
if (a.order_day.year < b.order_day.year) //id do it similar but a bit differently
return true;
if (a.order_day.year == b.order_day.year &&
a.order_day.month < b.order_day.month)
return true;
if (a.order_day.year == b.order_day.year &&
a.order_day.month == b.order_day.month &&
a.order_day.day < b.order_day.day)
return true;
// If none of the above cases satisfy, return false
return false;
}
static void sort_date(tech_info* all_orders[]) { //here you have double pointer *name[]. [] also acts as * so you have **all_orders
sort(all_orders, all_orders + counter, compare_date); //sort, assuming its sort() from #include <algorithms> uses i think single pointer to beginning of array, end array then type of sorting
cout << "Sorted by date. " << "\n"; //endl instead of "\n"
}
I'd do it like this:
#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;
struct Date
{
int day, month, year;
Date(int d, int m, int y) : day(d), month(m), year(y) {}
Date() {}
};
struct tech_info{
int order_num;
Date order_day; //Sort
string client;
string tech_type;
int serial_key;
string problem;
string technician_name;
string tech_fix;
int price;
int days_spent;
string status;
string order_type;
string urgency;
int problems_num;
//faults problems[10]; you didnt define what this faults structure was
//making contructor for this class would be perfect
tech_info(int orderNum, int dateDay, int dateMonth, int dateYear, string cl, string techType, int serial, ...)
: order_num(orderNum), Date(dateDay, dateMonth, dateYear), client(cl), tech_type(techType), serial_key(serial), ... {}
tech_info() {}
};
bool compare_date(const tech_info &a, const tech_info &b) //pointers to references
{
if (a.order_day.year == b.order_day.year) //if year is the same
{
if (a.order_day.month == b.order_day.month) //if month is same
{
if (a.order_day.day < b.order_day.day) return true; //if day is different
else return false;
}
else //if month is different
{
if (a.order_day.month < b.order_day.month) return true;
else return false;
}
}
else //if year is different
{
if (a.order_day.year < b.order_day.year) return true;
else return false;
}
}
void sort_date(vector<tech_info> &all_orders) { //i suggest all your tech_info put into vector + no static function
sort(all_orders.begin(), all_orders.end(), compare_date);
cout << "Sorted by date." << endl;
}
int main()
{
vector<tech_info> techInfo;
//to add:
techInfo.emplace_back(tech_info(1,2,3,4,"client","sometech", 1234));
//to remove:
techInfo.erase(techInfo.begin() + 0); //where 0 is the index of the item you want to delete from vector
sort_date(techInfo);
}
Hope this helps!!!

Unable to access vector value by index

#include<iostream>
#include<vector>
using namespace std;
class Stack
{
public:
int top;
vector<int> v;
Stack(int size)
{
top=0;
cout<<"Enter the values"<<endl;
for(int i=0; i<size; i++)
{
int val;
cin>>val;
v.push_back(val);
top++;
}
}
void push(int val)
{
v.push_back(val);
top++;
}
int pop()
{
int x=v[top];
top--;
return x;
}
void disp()
{
for(int j=top; j<=0; j--)
cout<<v[j]<<' ';
}
};
int main()
{
Stack s(3);
int k=s.pop();
cout<<k;
return 0;
}
I am trying to learn the basics of OOP.
Here, my Stack constructor and push function are working fine, but there is a problem with the pop and disp functions.
I'm assuming that I am using an incorrect syntax to access the elements of a vector(maybe?). Can anyone tell me where I am going wrong?
Also, the value of k always comes out to be 0.
You can use the vector functions
int k = s.back();
s.pop_back();
cout << k;
more informationhttp://www.cplusplus.com/reference/vector/vector/back/
You have a off-by-one index error.
The way you have implemented your class, when there are N items in the stack, the value of top is N.
Hence, top is not a valid index to access the elements of v. You can use:
int pop()
{
int x=v[top-1];
top--;
return x;
}
or
int pop()
{
top--;
int x=v[top];
return x;
}
As some of the other answers say, you can use the built-in vector functions to do these things (see pop_back and back.
However, if you want to define your own, I would use the vector.at(index) function. Addressing the values with the index as you have works, but it doesn't do any bounds checking at() does. Which would solve your problem above where your index isn't correct for the zero-based indexing of a vector.

C++ seg fault when printing a vector<int> element from a member function

I have a class with an int vector data member. I initialize the vector to 26 elements, all with value -99 in the constructor. I can cout element 0 in the constructor and it prints "-99". The constructor then calls another member function that doesn't modify the vector but when I try to cout element 0 from that function I get a segmentation fault. Below I've posted screenshots of the relevant parts of the header and the two member functions. To be specific the code works as posted but if I move line 26 to line 46 I get the seg fault. Any helpful suggestions? Thank you!
header file:
class Seq
{
private:
vector<int> assignments;
string original;
vector<Expression> sequence;
bool valid;
public:
void print_assignments();
Seq();
Seq(const string& s);
void parse(const string s, int);
vector<Expression> get_sequence();
void display_sequence();
void evaluate();
Constructior and the member function (parse) it calls. Moving the first cout statement the line below the second cout statement causes the fault.
Seq::Seq(const string& s)
{
original = s;
vector<int> assignments(26, -99);
parse(s, s.size());
cout << assignments[0] << endl;
}
void Seq::parse(const string s, int length)
{
Expression e;
string temp1, temp2;
int i = 0;
while((s[i] != ';')&&(i < length))
{
i++;
}
if(i>0)
{
temp1 = s.substr(0, i);
e.set(temp1);
sequence.push_back(e);
if(sequence.back().get_type() == 0)
{
cout << sequence.back().get_token(0).get_token()[0] << endl;
}
}
You have defined a local vector named "assignments" in the constructor which is shadowing the data member with the same name, so the data member "assignments" probably still has zero length, hence the seg fault.
Change
while((s[i] != ';')&&(i < length))
to
while(i < length && s[i] != ';')
In your version, if s is empty or i is already greater than length, you'll get an AV or a segfault.
Also, stop naming variables temp.

Trouble Using Template Bubblesort with Array of Structs

So my goal is to read in some data and sort it by population, but I have to use a sort that can accept multiple data types. I was instructed to use a template to do this, but every time I pass the array "results[i].pop" to my bubblesort function I receive the error
no matching function for call to ‘bubblesort(std::string&)’
bubblesort(results[i].pop);"
note: candidate is:
election.cpp:32:3: note: template T bubblesort(T*)
T bubblesort(T ar[])
^
election.cpp:32:3: note: template argument deduction/substitution failed:
election.cpp:106:34: note: cannot convert ‘results[i].election::pop’ (type ‘std::string {aka std::basic_string}’) to type ‘std::basic_string*’
bubblesort(results[i].pop);
Here's the code:
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <fstream>
#include <stdlib.h>
using namespace std;
struct election {
string party;
string state;
string pop;
string reps;
int ratio;
};
template <typename T>
void bubblesort(T ar[])
{
//Bubblesort
int n = 51;
int swaps = 1;
while(swaps)
{
swaps = 0;
for (int i = 0; i < n - 1; i++)
{
if (ar[i] > ar[i + 1])
{
swap(ar[i],ar[i+1]);
swaps = 1;
}
}
}
//End Bubblesort
}
void delete_chars(string & st, string ch)
{
int i = st.find(ch);
while (i > -1)
{
st.replace(i,1,"");
i = st.find(ch);
}
}
int main()
{
int i = 0;
int n = 51;
election results[n];
int population[n];
int electoralVotes[n];
int ratio[n];
string st;
fstream inData;
//Read in Data from Text File
inData.open("electionresults.txt");
//Print Array as is
cout << "Array Printed As is" << endl;
cout << left << setw(10) << "Party" << setw(20) << "State" << setw(20) << "Population" << setw(15) << "Representatives" << endl;
for (int i = 0; i < n; i++)
{
getline(inData,st);
results[i].party = st.substr(0,1);
results[i].state = st.substr(8,14);
results[i].pop = st.substr(24,10);
results[i].reps = st.substr(40,2);
cout << left << setw(10) << results[i].party << setw(20) << results[i].state << setw(20) << results[i].pop << setw(15) << results[i].reps << endl;
}
//Array Sorted by Population
cout << "Array Sorted By Population" << endl;
cout << endl;
cout << endl;
cout << left << setw(10) << "Party" << setw(20) << "State" << setw(20) << "Population" << setw(15) << "Representatives" << endl;
for(int i = 0; i < n; i++){
bubblesort<string>(results[i].pop);
}
For your bubblesort to work, you need to implement the greater than operator(>) for the election struct:
struct election
{
string party;
string state;
string pop;
string reps;
int ratio;
bool operator>( election a)
{
return pop > a.pop;
}
};
Now call the bubblesort by passing the results array:
bubblesort<election>(results);
A side note your function should pass in the size rather than hardcoding the size in the function(void bubblesort(T ar[], int size)). This gives your function much more functionality and adaptability.
The other answer addressed the issue if you only wanted to sort on pop. However, it is a limited solution, and won't address the real issue of sorting on any field (today it's "pop", but what if this isn't the case tomorrow, where you want to sort on "ratio"?). The issue is that you cannot provide more than one operator > to do this and you're basically stuck only sorting on pop.
Another solution is to provide the bubblesort function with an additional template parameter that defines what to do when given two T's, whether one T should be placed before the other T in the sorted array.
#include <functional>
#include <algorithm>
//...
template <typename T, typename cmp>
void bubblesort(T ar[], int n, cmp compare_fn)
{
int swaps = 1;
while (swaps)
{
swaps = 0;
for (int i = 0; i < n - 1; i++)
{
if (!compare_fn(ar[i], ar[i + 1]))
{
std::swap(ar[i], ar[i + 1]);
swaps = 1;
}
}
}
}
// keep our original 2 param bubble sort, but let it call the one above
template <typename T>
void bubblesort(T ar[], int n)
{
// call general version using <
bubblesort(ar, n, std::less<T>());
}
We basically have two functions, where the two parameter bubblesort function calls the general 3 parameter bubblesort version that takes a third parameter, which describes the comparison.
The two parameter version of bubblesort is used when you want to call bubblesort for the "simple" cases, where your items are
In an array and
You can compare T using < and
You want to sort in ascending order (which is why we used < and not > for the general case).
For example, an array of int needs to be sorted, and you simply want to sort it in ascending order:
int someArray[10];
//...
bubblesort<int>(someArray, 10); // sort ascending
However, we don't want to do a "simple" sort on int, or even std::string. We want to sort on election, and not only that, on election.pop.
If you look at the first bubblesort function above, note that we replaced the comparison using > with a call to a function compare_fn. Note that the parameter is defaulted to the std::less function object. This is why the second bubblesort function works for simple types, since std::less uses < to compare.
However, if you tried to call the bubblesort using only two parameters using election, you come across another compiler error, basically stating that election has no operator < to compare with. The solution to that is either
1) to provide such an operator < (similar to the other answer given) to the election struct or
2) Write a custom comparison function.
So let's go over each of these solutions.
Solution 1:
If we use 1), the election struct will look like this:
struct election
{
std::string party;
std::string state;
std::string pop;
std::string reps;
int ratio;
bool operator <(const election& e) const { return pop < e.pop; }
};
int main()
{
//...
bubblesort<election>(results, n);
}
This will now sort on results using pop as the item to sort on due to the operator < defined in election being used by std::less<>.
Here is an example using overloaded < in election
However, this solution has the same issues as the other answer, in that you can only define one operator < that takes a const election& as a parameter. If you wanted to sort on ratio, for example, you're out of luck, or if you want to sort pop in descending order, you're out of luck. This is where option 2) above will be used.
Solution 2:
We can define what we want to sort on, the sort order, etc. by providing a custom comparison function, function object, or lambda function that returns true if the first T should come before the second T that's passed into the comparison function, false otherwise.
Let's try a function:
bool compare_pop(const election& e1, const election& e2)
{
return e1.pop < e2.pop; // if e1.pop comes before e2.pop, return true, else false
}
int main()
{
//...
bubblesort<election>(results, n, compare_pop);
}
What will happen now is that this will call the first version of bubblesort that takes a comparison function as a parameter. The bubblesort template function will now call compare_pop to determine if the items are out of order. If compare_pop returns false the bubblesort function will swap the items, otherwise it will leave them alone.
Here is a live example with an array of 3 elections, sorted on pop
If you wanted to use a lambda function instead of writing another compare function, that will work too:
int main()
{
//...
bubblesort<election>(results, n, [&](const element& e1, const element& e2) { return e1.pop < e2.pop; });
}
The above will do the same thing as the function example, except that you no longer need to write a separate function as the lambda syntax is used as the function.
Example using lambda syntax
So now, what if we want to sort on pop, but descending and not ascending? Simple -- call bubblesort with a different function or lambda:
bool compare_pop_up(const election& e1, const election& e2)
{
return e1.pop > e2.pop; // if e1.pop comes after e2.pop, return true, else false
}
int main()
{
//...
bubblesort<election>(results, n, compare_pop_up);
}
or using lambda:
int main()
{
//...
bubblesort<election>(results, n,
[&](const element&e1, const element& e2)
{ return e1.pop > e2.pop;});
}
and magically, the bubblesort does the job, sorting on pop in descending order.
Here is a live example with an array of 3 elections, sorted on pop, descending
What if you want to sort on ratio? Same thing -- provide a different function or lambda:
bool compare_ratio(const election& e1, const election& e2)
{
return e1.ratio < e2.ratio;
}
int main()
{
//...
bubblesort<election>(results, n, compare_ratio);
}
or using lambda:
int main()
{
//...
bubblesort<election>(results, n,
[&](const element&e1, const element& e2)
{ return e1.ratio < e2.ratio;});
}
This will sort on ratio in ascending order of the ratio.
The other issue with your code is that you are using non-standard C++ syntax in defining your arrays. You're doing this:
election results[n];
This is not standard C++ syntax, as C++ only allows arrays to be created using a compile-time expression to denote the number of items. You're using something called Variable Length Arrays, which is not standard.
Instead, you can use std::vector, which is standard C++.
#include <vector>
//...
std::vector<election> results(n);
//...
bubblesort<election>(results.data(), results.size(), compare_pop)

Priority Queue Wrong Order

I am programming the huffman encoding. This is the beginning of my program:
using namespace std;
//Counting methods
int *CountCharOccurence(string text)
{
int *charOccurrence = new int[127];
for(int i = 0; i < text.length(); i++)
{
charOccurrence[text[i]]++;
}
return charOccurrence;
}
void DisplayCharOccurence(int *charOccurrence)
{
for(int i = 0; i < 127; i++)
{
if(charOccurrence[i] > 0)
{
cout << (char)i << ": " << charOccurrence[i] << endl;
}
}
}
//Node struct
struct Node
{
public:
char character;
int occurrence;
Node(char c, int occ) {
character = c;
occurrence = occ;
}
bool operator < (const Node* node)
{
return (occurrence < node->occurrence);
}
};
void CreateHuffmanTree(int *charOccurrence)
{
priority_queue<Node*, vector<Node*> > pq;
for(int i = 0; i < 127; i++)
{
if(charOccurrence[i])
{
Node* node = new Node((char)i, charOccurrence[i]);
pq.push(node);
}
}
//Test
while(!pq.empty())
{
cout << "peek: " << pq.top()->character << pq.top()->occurrence << endl;
pq.pop();
}
}
int main(int argc, char** argv) {
int *occurrenceArray;
occurrenceArray = CountCharOccurence("SUSIE SAYS IT IS EASY");
DisplayCharOccurence(occurrenceArray);
CreateHuffmanTree(occurrenceArray);
return (EXIT_SUCCESS);
}
The program first outputs the characters with their occurence number. This looks fine:
: 4
A: 2
E: 2
I: 3
S: 6
T: 1
U: 1
Y: 2
but the test loop which has to display the node contents in priority order outputs this:
peek: Y2
peek: U1
peek: S6
peek: T1
peek: I3
peek: E2
peek: 4
peek: A2
This is not the expected order. Why?
Elements in your priority queue are pointers. Since you don't provide a function that takes 2 pointers to Node objects , default compare function compares 2 pointers.
bool compareNodes(Node* val1, Node* val2)
{
return val1->occurence < val2->occurence;
}
priority_queue<Node*, vector<Node*>,compareNodes > pq;
Your operator < is used when Node compares with Node*
You should tell your priority queue what it should sort by. In your case, you have to tell it to sort by Node::occurence.
You are storing pointers to nodes in the queue, but haven't provided a suitable comparison function, so they are sorted by comparing the pointers. The operator< you've provided will compare a node with a pointer, which isn't what you want.
There are two options:
Provide a function for comparing two node pointers according to their values, and give this function to the queue, or
Store node objects in the queue, and provide an operator< to compare two nodes.
The second option will also fix the memory leak in your code, and remove a whole pile of unnecessary memory allocations, so I would suggest that.