How to fix the error "Assertion '__pos <= size' failed"? - c++

void Route(int start, int end, int max, vector<string> a, vector<string>& vec) {
if (start == end) {
string str = "";
bool invalid = false;
int continuous = 1;
for (int i = 0; i < end; i++){
string num_str1 = a[i];
if(num_str1[0]==str.back()){
continuous += 1;
if (continuous>max){
invalid = true;
}
}else{
continuous = 1;
}
str = str+num_str1;
}
if (vec.size()>0&&!invalid){
bool contains = false;
for (int i=0; i<vec.size();i++){
if (vec[i]==str){contains = true;}
}
if(!contains){
vec.push_back(str);
}
} else if (vec.size()==0&&!invalid){ vec.push_back(str);}
return;
}
I tested several times, I'm pretty sure it's code inside the first for loop that causes this error below:
/builddir/build/BUILD/gcc-8.5.0-20210514/obj-x86_64-redhat-linux/x86_64-redhat-linux/libstdc++-v3/include/bits/basic_string.h:1149: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::reference std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::back() [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::reference = char&]: Assertion '!empty()' failed.
The code works fine when I run it on vscode, but it always failed in linux machine! How can I fix it?

Related

Error using std::set to implement a sparse 3D grid

I'm trying to implement a sparse 3D grid with std::set container, but I can't understand the error returned from the compiler, this is the minimal example I'm trying to run:
#include <iostream>
#include <vector>
#include <limits>
#include <set>
#include <Eigen/Core>
using namespace std;
class Cell {
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
Cell(const Eigen::Vector3i idx=Eigen::Vector3i::Zero()):_idx(idx) {
_center = Eigen::Vector3f::Zero();
_parent = 0;
_distance = std::numeric_limits<int>::max();
}
inline bool operator < (const Cell& c){
for (int i=0; i<3; i++){
if (_idx[i]<c._idx[i])
return true;
if (_idx[i]>c._idx[i])
return false;
}
return false;
}
inline bool operator == (const Cell& c) { return c._idx == _idx;}
private:
Eigen::Vector3i _idx;
Eigen::Vector3f _center;
vector<Eigen::Vector3f> _points;
Cell* _parent;
size_t _closest_point;
float _distance;
int _tag;
};
int main(int argc, char* argv[]) {
set<Cell> grid;
float max = 1, min = -1;
int dim = 5;
float delta = (max-min)/(dim-1);
for(int k = 0; k < dim; k++)
for(int j = 0; j < dim; j++)
for(int i = 0; i < dim; i++)
grid.insert(Cell(Eigen::Vector3i(i,j,k)));
return 0;
}
and this is the compiler error:
In file included from /usr/include/c++/4.8/string:48:0,
from /usr/include/c++/4.8/bits/locale_classes.h:40,
from /usr/include/c++/4.8/bits/ios_base.h:41,
from /usr/include/c++/4.8/ios:42,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from /home/dede/build/sparse_grid/main.cpp:1: /usr/include/c++/4.8/bits/stl_function.h: In instantiation of 'bool
std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp =
Cell]': /usr/include/c++/4.8/bits/stl_tree.h:1324:11: required from
'std::pair
std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::_M_get_insert_unique_pos(const key_type&) [with _Key = Cell; _Val = Cell; _KeyOfValue = std::_Identity; _Compare = std::less; _Alloc = std::allocator; std::_Rb_tree<_Key,
_Val, _KeyOfValue, _Compare, _Alloc>::key_type = Cell]' /usr/include/c++/4.8/bits/stl_tree.h:1377:47: required from
'std::pair, bool> std::_Rb_tree<_Key,
_Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_Arg&&) [with _Arg = Cell; _Key = Cell; _Val = Cell; _KeyOfValue = std::_Identity; _Compare = std::less; _Alloc =
std::allocator]' /usr/include/c++/4.8/bits/stl_set.h:472:40:
required from 'std::pair, _Compare, typename
_Alloc::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(std::set<_Key, _Compare, _Alloc>::value_type&&) [with _Key = Cell; _Compare = std::less; _Alloc = std::allocator; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename
_Alloc::rebind<_Key>::other>::const_iterator = std::_Rb_tree_const_iterator; std::set<_Key, _Compare,
_Alloc>::value_type = Cell]' /home/dede/build/sparse_grid/main.cpp:53:57: required from here
/usr/include/c++/4.8/bits/stl_function.h:235:20: error: passing 'const
Cell' as 'this' argument of 'bool Cell::operator<(const Cell&)'
discards qualifiers [-fpermissive]
{ return __x < __y; }
^ make[2]: * [CMakeFiles/sparse_grid.dir/main.cpp.o] Error 1 make[1]: *
[CMakeFiles/sparse_grid.dir/all] Error 2 make: *** [all] Error 2
I would really appreciate if someone could tell me what I'm doing wrong.
Thanks,
Federico
You should declare your boolean operator functions as const members:
inline bool operator < (const Cell& c) const {
// ^^^^^
for (int i=0; i<3; i++){
if (_idx[i]<c._idx[i])
return true;
if (_idx[i]>c._idx[i])
return false;
}
return false;
}
inline bool operator == (const Cell& c) const { return c._idx == _idx;}
// ^^^^^
Otherwise these cannot be used with rvalue objects of Cell.
You have defined operator < in Cell, but the error says it wants bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = Cell]. Notice you should make your member function const.
You could provide a non-member function for less, which can use your member function, once the it is const.
bool operator <(const Cell &a, const Cell &b)
{
return a < b;
}
However, std::less will provide this for you, provided your member function is const.
You have declared your Parameters for > and == operators overloads as const and you are passing a temporary.
Just create a temporary Object of Cell within the loop and insert it in cell
Do it like this :
for(int k = 0; k < dim; k++)
for(int j = 0; j < dim; j++)
for(int i = 0; i < dim; i++)
{
Eigen::Vector3i(i,j,k) eigenVec;
Cell cell(eigenVec);
grid.insert(cell);
}
Your compilation should succeed.

Compiling error when insert pair into set [duplicate]

This question already has answers here:
problems with c++ set container
(2 answers)
Closed 6 years ago.
I can't understand why g++ returns error like this:
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_pair.h: In function 鈥榖ool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&) [with _T1 = int, _T2 = stop]鈥
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_function.h:227: instantiated from 鈥榖ool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = std::pair<int, stop>]鈥
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_tree.h:921: instantiated from 鈥榮td::pair<typename std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::insert_unique(const _Val&) [with _Key = std::pair<int, stop>, _Val = std::pair<int, stop>, _KeyOfValue = std::_Identity<std::pair<int, stop> >, _Compare = std::less<std::pair<int, stop> >, _Alloc = std::allocator<std::pair<int, stop> >]鈥
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_set.h:321: instantiated from 鈥榮td::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const _Key&) [with _Key = std::pair<int, stop>, _Compare = std::less<std::pair<int, stop> >, _Alloc = std::allocator<std::pair<int, stop> >]鈥
newGraph.cpp:48: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_pair.h:104: error: no match for 鈥榦perator<鈥in 鈥榑_x->std::pair<int, stop>::second < __y->std::pair<int, stop>::second鈥
Here is my code:
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <set>
#include <utility> // for pair
#include <algorithm>
#include <iterator>
const int max_weight = INT_MAX;
struct stop {
std::string name_stop;
int id_stop;
bool operator !=(const stop &rhs) const
{
return ((id_stop != rhs.id_stop) || (name_stop != rhs.name_stop));
}
};
struct neighbor {
stop target;
int weight;
neighbor(stop arg_target, int arg_weight) : target(arg_target), weight(arg_weight) { }
};
std::list<stop> dijkstraComputeAndGetShortestPaths(stop src,
stop dst,
std::vector< std::vector<neighbor> > &adj_list,
std::vector<int> &min_distance,
std::vector<stop> &previous)
{
stop fake_stop;
fake_stop.id_stop = INT_MAX;
fake_stop.name_stop = "Null";
std::list<stop> path;
int n = adj_list.size();
min_distance.clear();
min_distance.resize(n, max_weight);
min_distance[src.id_stop] = 0;
previous.clear();
previous.resize(n, fake_stop);
std::set< std::pair< int, stop > > vertex_queue;
vertex_queue.insert(std::make_pair(min_distance[src.id_stop], src));
while (!vertex_queue.empty())
{
int dist = vertex_queue.begin()->first;
stop u = vertex_queue.begin()->second;
vertex_queue.erase(vertex_queue.begin());
// Visit each edge exiting u
const std::vector<neighbor> &neighbors = adj_list[u.id_stop];
for(std::vector<neighbor>::const_iterator neighbor_iter = neighbors.begin();
neighbor_iter != neighbors.end();
neighbor_iter++)
{
stop v = neighbor_iter->target;
int weight = neighbor_iter->weight;
int distance_through_u = dist + weight;
if (distance_through_u < min_distance[v.id_stop]) {
vertex_queue.erase(std::make_pair(min_distance[v.id_stop], v));
min_distance[v.id_stop] = distance_through_u;
previous[v.id_stop] = u;
vertex_queue.insert(std::make_pair(min_distance[v.id_stop], v));
}
}
if(u.id_stop == dst.id_stop)
{
std::cout << "Find : ";
for ( ; dst != fake_stop; dst = previous[dst.id_stop])
{
path.push_front(dst);
}
return path;
}
}
}
int main()
{
std::vector< std::vector<neighbor> > adj_list(9);
stop stop_s;
stop_s.id_stop = 1001;
stop_s.name_stop = "A";
stop stop_x;
stop_x.id_stop = 1002;
stop_x.name_stop = "B";
adj_list[stop_s.id_stop].push_back(neighbor(stop_x, 5));
stop_s.id_stop = 1003;
stop_s.name_stop = "C";
adj_list[stop_x.id_stop].push_back(neighbor(stop_s, 15));
stop_x.id_stop = 1004;
stop_x.name_stop = "D";
adj_list[stop_s.id_stop].push_back(neighbor(stop_x, 20));
stop_s.id_stop = 1001;
stop_s.name_stop = "A";
std::vector<int> min_distance;
std::vector<stop> previous;
std::list<stop> path = dijkstraComputeAndGetShortestPaths(stop_s, stop_x, adj_list, min_distance, previous);
std::cout << "Distance from 1001 to 1004: " << min_distance[stop_x.id_stop] << std::endl;
//std::cout << "Path : ";
#if 0
for (int index = 0; index < path.size(); index++)
{
auto path_front = path.begin();
std::advance(path_front, index);
std::cout << path_front->id_stop << " ";
}
std::cout << std::endl;
#endif
return 0;
}
std::set require you to specify an operator < for the type it holds or you can supply your own comparison functor as a template parameter. Since stop does not have an operator < the operator < from std::pair is not compileable since it relies on using the operator < of the types it holds.. You either need to supply your own comparison functor or define an operator < for stop.

Store strings in a vector and sort them

I want to make a class that stores strings from the console in a vector and then sorts them alphabetically using selection sort.
This is my code so far.
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
class Dictionary
{
public:
Dictionary();
void read(vector<int>&words);
void SelectionSort(vector <int> &num);
private:
//vector<string> line_vector;
string word;
//vector<string> words;
};
Dictionary:: Dictionary()
{
//line_vector = "<empty>";
string word = "<empty>";
}
void Dictionary:: read(vector<int>& words)
{
//vector<string> words;
string word;
while( cin >> word ) words.push_back(word);
}
////////////////////////////////////////////////////////////////////////////////////
void Dictionary:: SelectionSort(vector <int> &num)
{
int i, j, first, temp;
int numLength = num.size( );
for (i= numLength - 1; i > 0; i--)
{
first = 0; // initialize to subscript of first element
for (j=1; j<=i; j++) // locate smallest between positions 1 and i.
{
if (num[j] < num[first])
first = j;
}
temp = num[first]; // Swap smallest found with element in position i.
num[first] = num[i];
num[i] = temp;
}
return;
}
void print(vector<Dictionary>& a)
{
for (int i = 0; i < a.size(); i++)
cout << a[i];
cout << "\n";
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
Dictionary dict;
vector<Dictionary> str;
dict.read(str);
dict.SelectionSort(str);
dict.print(str);
return 0;
}
and these are the errors:
In member function 'void Dictionary::read(std::vector<int>&)':
31:46: error: no matching function for call to 'std::vector<int>::push_back(std::string&)'
31:46: note: candidates are:
In file included from /usr/include/c++/4.9/vector:64:0,
from 3:
/usr/include/c++/4.9/bits/stl_vector.h:913:7: note: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::value_type = int]
push_back(const value_type& __x)
^
/usr/include/c++/4.9/bits/stl_vector.h:913:7: note: no known conversion for argument 1 from 'std::string {aka std::basic_string<char>}' to 'const value_type& {aka const int&}'
/usr/include/c++/4.9/bits/stl_vector.h:931:7: note: void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::value_type = int]
push_back(value_type&& __x)
^
One of the error lines seems very helpful:
/usr/include/c++/4.9/bits/stl_vector.h:913:7: note:
no known conversion for argument 1
from
'std::string {aka std::basic_string<char>}'
to
'const value_type& {aka const int&}'
If you pass an argument that doesn't match the expected type for a function, then C++ will try to find any conversion from the passed type into the expected type. The conversion include 1-argument constructors and cast operators. See http://www.cplusplus.com/doc/tutorial/typecasting/
This particular error is indicating that the passed argument cannot be converted to an int.

no matching function for vector<string>::push_back(stringstream&)

So I was writing an algorithm for a TopCoder problem and I got the following errors. I have tried my best to eliminate syntax errors but I can't seem to figure out what is warranting these errors. Can you help me out with it? I am not very experienced and I'm trying to learn.
tc1.cpp: In member function ‘std::vector<std::basic_string<char> > BinaryCode::decode(std::string)’:
tc1.cpp:46:20: error: no matching function for call to ‘std::vector<std::basic_string<char> >::push_back(std::stringstream&)’
tc1.cpp:46:20: note: candidate is:
/usr/include/c++/4.6/bits/stl_vector.h:826:7: note: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::basic_string<char>, _Alloc = std::allocator<std::basic_string<char> >, std::vector<_Tp, _Alloc>::value_type = std::basic_string<char>]
/usr/include/c++/4.6/bits/stl_vector.h:826:7: note: no known conversion for argument 1 from ‘std::stringstream {aka std::basic_stringstream<char>}’ to ‘const value_type& {aka const std::basic_string<char>&}’
make: *** [tc1] Error 1
The code I've written is -
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
class BinaryCode
{
public:
vector<string> decode(string message)
{
int cntrl = 0;
vector<string> P;
bool poss = true;
int a = message.length();
int A[a+2], B[a+2];
for (int i=1; i<=a ; i++)
{
stringstream ss(message.substr(i,1));
ss >> B[i];
}
while (cntrl <2)
{
A[0] = A[a+1] = cntrl;
for (int i=0; i<=a; i++)
{
A[1] = B[2] - cntrl;
A[i+1] = B[i] - A[i] - A[i-1];
if (A[i+1]<0 || A[i+1])
{
poss = false;
}
}
if (!poss)
P.push_back("NONE");
else
{
stringstream s;
for (int i =0; i<a+2; i++)
s << (char)A[i];
P.push_back(s);
}
cntrl++;
}
return P;
}
};
int main()
{
BinaryCode ob;
string str;
cout << "Enter the encrypted string: " << endl;
cin >> str;
vector<string> vec = ob.BinaryCode::decode(str);
vector<string>::iterator it = vec.begin();
for (; it!= vec.end(); it++) {
cout << *it;
}
}
I'd be grateful if someone could point out what I'm doing wrong with this.
You are pushing a stringstream into a vector of strings. Change
P.push_back(s);
to
P.push_back(s.str());

Calculator.cpp:48:24: error: invalid conversion from 'char' to 'const char*' [-fpermissive]

Here's my disclosure: I am doing a school project in which I use a linked stack to implement a postfix calculator.
My issue today is that I am getting a weird (to me) error in my code that I cannot seem to get around. The logic I can figure out with time, it's these syntactical things that I need to work on (and I figure with practice that will come naturally).
Anyways, I want to know what's causing this error, and why. From what I researched, it has something to do with strings and char comparisons, but that's the limit of my knowledge.
Update: I threw in some asterisks next to the errors occur in my code
The error block I get on the school's compiler is as follows:
In file included from Calculator.h:35:0,
from CalculatorMain.cpp:6:
Calculator.cpp: In member function 'void Calculator::performOp(const string&)':
Calculator.cpp:48:24: error: invalid conversion from 'char' to 'const char*' [-fpermissive]
/opt/csw/lib/gcc/i386-pc-solaris2.10/4.6.3/../../../../include/c++/4.6.3/bits/basic_string.tcc:214:5: error: initializing argument 1 of 'std::basic_string<_CharT, aits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]' [-fpermissive]
Calculator.cpp:52:30: error: invalid conversion from 'char' to 'const char*' [-fpermissive]
/opt/csw/lib/gcc/i386-pc-solaris2.10/4.6.3/../../../../include/c++/4.6.3/bits/basic_string.tcc:214:5: error: initializing argument 1 of 'std::basic_string<_CharT, aits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]' [-fpermissive]
Calculator.cpp:53:101: error: invalid conversion from 'char' to 'const char*' [-fpermissive]
/opt/csw/lib/gcc/i386-pc-solaris2.10/4.6.3/../../../../include/c++/4.6.3/bits/basic_string.tcc:214:5: error: initializing argument 1 of 'std::basic_string<_CharT, aits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]' [-fpermissive]
Calculator.cpp:57:27: error: invalid conversion from 'char' to 'const char*' [-fpermissive]
/opt/csw/lib/gcc/i386-pc-solaris2.10/4.6.3/../../../../include/c++/4.6.3/bits/basic_string.tcc:214:5: error: initializing argument 1 of 'std::basic_string<_CharT, aits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]' [-fpermissive]
Calculator.cpp:60:23: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
Calculator.cpp:61:27: error: invalid conversion from 'char' to 'const char*' [-fpermissive]
/opt/csw/lib/gcc/i386-pc-solaris2.10/4.6.3/../../../../include/c++/4.6.3/bits/basic_string.tcc:214:5: error: initializing argument 1 of 'std::basic_string<_CharT, aits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]' [-fpermissive]
Calculator.cpp:64:23: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
My code in my calculator class (for calculator.cpp. The header file is seperate):
** #file Calculator.cpp */
#include <string>
#include <cassert>
#include "Calculator.h"
Calculator::Calculator(){
} // end default constructor
bool Calculator::isOperator(const string& newEntry) {
string ops[] = {"-", "+", "/", "*"};
for (int i = 0; i < 4; i++) {
if (newEntry == ops[i]) {
return true;
}
}
return false;
}
bool Calculator::isOperand(const string& newEntry) {
if (!isOperator(newEntry) && newEntry != "(" && newEntry != ")") {
return true;
}
return false;
}
int Calculator::compareOps(const string& op1,const string& op2) {
if ((op1 == "*" || op1 == "/") && (op2 == "+" || op2 == "-")) {
return -1;
}
else if ((op1 == "+" || op1 == "-") && (op2 == "*" || op2 == "/")) {
return 1;
}
return 0;
}
void Calculator::performOp(const string& userExpression) {
string temp = userExpression;
int i = 0;
cout << "Error log: User expression is now " << temp << endl;
while(temp[i] > temp.length()) {
cout << "Error log: begin while loop" << endl;
**if (isOperand(temp[i])) {**
postfixString += temp[i];
}
else if **(isOperator(temp[i]))** {
**while (!infixStack.isEmpty() && infixStack.peek() != "(" && compareOps(infixStack.peek(), temp[i]) <= 0) {**
postfixString += infixStack.peek();
infixStack.pop();
}// end while
infixStack.push(temp[i]);
}
**else if (temp[i] == "(") {**
infixStack.push(temp[i]);
}
**else if (temp[i] == ")") {**
while (!infixStack.isEmpty()) {
if (infixStack.peek() == "(") {
infixStack.pop();
break;
}
postfixString += infixStack.peek();
infixStack.pop();
}//end while
}//end last else if
i++;
}//end while
while(!infixStack.isEmpty()) {
postfixString += infixStack.peek();
infixStack.pop();
}
cout << "The Postfix form of your expression is: " << postfixString << endl;
}
And here is my file that tests this class:
#include <iostream>
#include <string>
#include "Calculator.h"
using namespace std;
int main()
{
Calculator aCalculator;
string userString = "1+1";
cout << "Testing the Link-Based Stack:" << endl;
aCalculator.performOp(userString);
return 0;
} // end main
Some of your functions expect strings but you are passing single chars. For example, isOperator should be:
bool Calculator::isOperator(char newEntry) {
char ops[] = {'-', '+', '/', '*'};
for (int i = 0; i < 4; i++) {
if (newEntry == ops[i]) {
return true;
}
}
return false;
}
Because you are calling it like: isOperator(temp[i]) and temp[i] returns a char, not a string.
There are many other places where you are mixing chars and strings.