Segmentation fault with GMP - c++

I have a program that reads a matrix from a file and stores it in the variable basis_MP, which is an instance variable. Since the values read from the files are very big (don't fit in native datatypes), I use GMP for a higher precision. I print the values of the matrix where the file is stored and they are correct.
After reading the file, I also initialize some other auxiliary variables that also use GMP. I declared them as instance variables, because I don't want to allocate and free them on each call to other methods. As soon as the line of code that initializes the first of them is executed, I get a segmentation fault.
basis.h:
#ifndef BASIS_H
#define BASIS_H
#include <math.h>
#include <gmp.h>
using namespace std;
class Basis {
private:
int rank; //No. vectors in the basis (also called n)
int dimension; //Dimension of each vector in the basis (also called m)
mpz_t **basis_MP; //Matrix containing all the vectors in the basis
mpf_t aux_MP_f0;
mpf_t aux_MP_f1;
mpf_t aux_MP_f2;
public:
Basis(); //Empty constructor
Basis(char *filename); //Constructor from file
}
basis_MP is the variable where the matrix is sotred, while aux_MP_f0, aux_MP_f1, aux_MP_f2 are the 3 auxiliary variables. All of them use GMP for a higher precision. In the constructor Basis(char *filename) all of these variables are initialized and the matrix is read.
basis.cpp:
#include "basis.h"
Basis::Basis() // Empty constructor
{
}
Basis::Basis(char* filename) // Constructor from file
{
char delim[] = " \n[]";
ifstream stream;
stream.open(filename);
if(!stream) cerr << "File was not read" << endl;
stream.seekg (0, stream.end);
int length = stream.tellg();
stream.seekg (0, stream.beg);
char * buffer = new char [length];
char * number = new char [length];
std::cout << "Reading " << length << " characters... " << endl;
stream.read (buffer,length);
int count = 0;
for (int i = 0; i < length; i++){
if (buffer[i] == '\n') {
count++;
break;
}
if (buffer[i] == ' ') {
count++;
}
}
dimension = count;
rank = count;
basis_MP = (mpz_t**)malloc(rank*sizeof(mpz_t*));
for (int i = 0; i < rank; i++)
basis_MP[i] = (mpz_t*)malloc(dimension*sizeof(mpz_t));
number = strtok(buffer, delim);
for (int i = 0; i < rank; i++) {
for (int j = 0; j < dimension; j++) {
mpz_init_set_str(basis_MP[i][j], number, 10);
number = strtok(NULL, delim);
}
}
stream.close();
mpf_init2(aux_MP_f0, mpz_sizeinbase(basis_MP[0][0], 2));
mpf_init2(aux_MP_f1, mpz_sizeinbase(basis_MP[0][0], 2));
mpf_init2(aux_MP_f2, mpz_sizeinbase(basis_MP[0][0], 2));
delete buffer;
delete number;
}
The auxiliary variables are initialized with the precision of the first vector of the matrix. The segmentation fault occurs on this line: mpf_init2(aux_MP_f0, mpz_sizeinbase(basis_MP[0][0], 2));
main.cpp:
#include "basis.h"
int main (int argc, char **argv) {
Basis *b = new Basis(argv[1]);
}
The error I get is the following:
Program received signal SIGSEGV, Segmentation fault.
_int_malloc (av=0x7ffff7114760 <main_arena>, bytes=144) at malloc.c:3489
3489 malloc.c: No such file or directory.
Output of the backtrace from gdb:
(gdb) bt
#0 _int_malloc (av=0x7ffff7114760 <main_arena>, bytes=144) at malloc.c:3489
#1 0x00007ffff6dd92f0 in __GI___libc_malloc (bytes=144) at malloc.c:2891
#2 0x00007ffff7b71829 in __gmp_default_allocate () from /home/fcorreia/install/gmpxx/lib/libgmp.so.10
#3 0x00007ffff7b721db in __gmpf_init2 () from /home/fcorreia/install/gmpxx/lib/libgmp.so.10
#4 0x000000000040208f in Basis::Basis (this=0x607010, filename=0x7fffffffea8c "/home/project/dim10.txt") at src/basis.cpp:55
#5 0x000000000040517b in main (argc=2, argv=0x7fffffffe818) at src/main.cpp:4
I also tried replacing mpf_init2 by mpf_init and got the following error:
*** Error in `/home/project/a.out': malloc(): memory corruption: 0x0000000000608080 ***
Program received signal SIGABRT, Aborted.
0x00007ffff6d8ce37 in __GI_raise (sig=sig#entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
And the corresponding backtrace:
(gdb) bt
#0 0x00007ffff6d8ce37 in __GI_raise (sig=sig#entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1 0x00007ffff6d8e528 in __GI_abort () at abort.c:89
#2 0x00007ffff6dceb04 in __libc_message (do_abort=1, fmt=fmt#entry=0x7ffff6ed7a80 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3 0x00007ffff6dd829b in malloc_printerr (ptr=0x608080, str=0x7ffff6ed3bda "malloc(): memory corruption", action=<optimized out>) at malloc.c:4996
#4 _int_malloc (av=0x7ffff7114760 <main_arena>, bytes=24) at malloc.c:3447
#5 0x00007ffff6dd92f0 in __GI___libc_malloc (bytes=24) at malloc.c:2891
#6 0x00007ffff7b71829 in __gmp_default_allocate () from /home/install/gmpxx/lib/libgmp.so.10
#7 0x00007ffff7b72190 in __gmpf_init () from /home/install/gmpxx/lib/libgmp.so.10
#8 0x00000000004020fc in Basis::Basis (this=0x608010, filename=0x7fffffffea8c "/home/project/dim10.txt") at src/basis.cpp:55
#9 0x0000000000405219 in main (argc=2, argv=0x7fffffffe818) at src/main.cpp:4
Somewhere the memory is being corrupted and I can't figure out where. Probably, I'm not using gmp correct. Does anyone have some hints?
Thanks

Related

Why there is a segmentation fault when calling printf from a class? [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 1 year ago.
Improve this question
This is the relevant part (I think) of my source code
#include <iostream>
#include <cstdarg>
#include <cstring>
#include <cstdlib>
class Poly
{
private:
double *coefficients;
size_t degree;
inline double *cfp(size_t i);
public:
Poly();
Poly(size_t n, ...);
void Print() const;
~Poly();
};
Poly::Poly()
{
this->degree = 0;
this->coefficients = new double(1);
*(this->coefficients) = 1.;
}
Poly::Poly(size_t n, ...)
{
va_list coefs;
va_start(coefs, n);
this->degree = n;
n++;
register double *cfs = new double(n);
this->coefficients = cfs;
while (n--)
{
*cfs = va_arg(coefs, double);
cfs++;
}
va_end(coefs);
}
void Poly::Print() const
{
bool started = false;
double c = this->cf(0);
putchar('a');
std::cout << this->degree << '\n';
if (c != 0.)
{
std::cout << c;
started = true;
}
size_t N = this->degree;
for (size_t i = 1; i <= N; i++)
{
c = this->cf(i);
if (c != 0.)
{
if (!started)
started = true;
else
std::cout << ((c < 0.) ? " - " : " + ");
//printf(" + ");
std::cout << fabs(c) << " x^" << i;
//printf("%lf x^%lu", c, i);
}
}
printf("\n");
}
Poly::~Poly()
{
delete this->coefficients;
}
int main()
{
//printf("\n"); <- Uncommenting this line stops the error
Poly p1(7, 1., 3., -9., 2., 0., 8., -2., 6.);
p1.Print();
}
Right now, Print method has many printfs and couts. But when I uncomment the line from main, malloc brings segmentation fault at the first print or cout or even putchar from the 'Print` method. I cannot find any memory leaks there. Why does it happen and how to prevent it?
I am using gcc (g++) 9.3.0 on WSL Ubuntu. The program is compiled with the flags -lc -g.
gdb showed me this
malloc(): corrupted top size
Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig#entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) backtrace
#0 __GI_raise (sig=sig#entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007ffff7c0f859 in __GI_abort () at abort.c:79
#2 0x00007ffff7c7a3ee in __libc_message (action=action#entry=do_abort, fmt=fmt#entry=0x7ffff7da4285 "%s\n")
at ../sysdeps/posix/libc_fatal.c:155
#3 0x00007ffff7c8247c in malloc_printerr (str=str#entry=0x7ffff7da2556 "malloc(): corrupted top size") at malloc.c:5347
#4 0x00007ffff7c8583a in _int_malloc (av=av#entry=0x7ffff7dd5b80 <main_arena>, bytes=bytes#entry=1024) at malloc.c:4107
#5 0x00007ffff7c872d4 in __GI___libc_malloc (bytes=1024) at malloc.c:3058
#6 0x00007ffff7c6ee84 in __GI__IO_file_doallocate (fp=0x7ffff7dd66a0 <_IO_2_1_stdout_>) at filedoalloc.c:101
#7 0x00007ffff7c7f050 in __GI__IO_doallocbuf (fp=fp#entry=0x7ffff7dd66a0 <_IO_2_1_stdout_>) at libioP.h:948
#8 0x00007ffff7c7e0b0 in _IO_new_file_overflow (f=0x7ffff7dd66a0 <_IO_2_1_stdout_>, ch=97) at fileops.c:745
--Type <RET> for more, q to quit, c to continue without paging--
#9 0x00007ffff7c73482 in putchar (c=97) at putchar.c:28
#10 0x0000555555555cfe in Poly::Print (this=0x7fffffffdb90) at polynomial_r.cpp:241
#11 0x0000555555555fd2 in main () at test.cpp:7
(gdb) info frame
Stack level 0, frame at 0x7fffffffd6f0:
rip = 0x7ffff7c3018b in __GI_raise (../sysdeps/unix/sysv/linux/raise.c:50); saved rip = 0x7ffff7c0f859
called by frame at 0x7fffffffd820
source language c.
Arglist at 0x7fffffffd5c8, args: sig=sig#entry=6
Locals at 0x7fffffffd5c8, Previous frame's sp is 0x7fffffffd6f0
Saved registers:
rip at 0x7fffffffd6e8
(gdb)
Looks like you corrupted your heap by writing past the end of your heap-allocation. I think your problem is here:
register double *cfs = new double(n);
Note that the above code allocates a single double set to value n, when I think what you wanted to do was allocate an array of n doubles. To do that you'd need to use brackets instead of parentheses:
register double *cfs = new double[n];

ERROR: UndefinedBehaviorSanitizer:DEADLYSIGNAL

I keep receiving same error after compilation my CodeWars code. Tried to handle with all warnings and though after that it keeps popping up anyway.I checked the same questions and some of them had been resolved by manipulating with boundaries or memory allocation. But, here, i can't understand where the actual error lies in the code.
Here is my code:
#include <vector>
#include <numeric>
#include <iostream>
#include <algorithm>
using namespace std;
int maxSequence(const vector<int>& arr)
{
vector <unsigned long> temp2;
vector <unsigned long> temp1;
int result,sum_max = 0;
for(unsigned long i = 0; i < arr.size(); ++i)
{
sum_max = arr[i];
for(unsigned long j = i+1; j < arr.size(); ++j)
{
sum_max += arr[j];
temp1.push_back(sum_max);
}
result = *max_element(temp1.begin(), temp1.end());
temp1.clear();
temp2.push_back(result);
}
result = *max_element(temp2.begin(),temp2.end());
return result;
}
Screenshot1
Screenshot2
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==1==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000425881 bp 0x7ffe7abb2300 sp 0x7ffe7abb1e10 T1)
==1==The signal is caused by a READ memory access.
==1==Hint: address points to the zero page.
==1==WARNING: invalid path to external symbolizer!
==1==WARNING: Failed to use and restart external symbolizer!
#0 0x425880 (/workspace/test+0x425880)
#1 0x4282de (/workspace/test+0x4282de)
#2 0x426a6e (/workspace/test+0x426a6e)
#3 0x4265e9 (/workspace/test+0x4265e9)
#4 0x42622b (/workspace/test+0x42622b)
#5 0x42aa55 (/workspace/test+0x42aa55)
#6 0x42599d (/workspace/test+0x42599d)
#7 0x7f9e4fd4ebf6 (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
#8 0x404519 (/workspace/test+0x404519)
UndefinedBehaviorSanitizer can not provide additional info.
==1==ABORTING
The problem was that i tried to submit my code without checking all required conditions. So,I had to add if-statement in case input vector is empty.
if (arr.size() == 0){return 0;} or if(arr.empty()){return 0;}

Why does the below multi threaded code result in SIGABRT ?

The below code i have blows up when run with switch flag that enables mutex protection. ie run as ./code.out 1
Now the stack trace of core dump points towards memory allocation issue perhaps happening from the fact that every insert from the thread results in a realloc of the whole vector due to size increasing beyond the reserved memory initially.
The trace is :
\#0 0x00007f1582ce6765 in raise () from /lib64/libc.so.6
\#1 0x00007f1582ce836a in abort () from /lib64/libc.so.6
\#2 0x00007f1582d27710 in __libc_message () from /lib64/libc.so.6
\#3 0x00007f1582d2feaa in _int_free () from /lib64/libc.so.6
\#4 0x00007f1582d3340c in free () from /lib64/libc.so.6
\#5 0x0000000000403348 in __gnu_cxx::new_allocator<int>::deallocate(int*, unsigned long) ()
\#6 0x00000000004029b2 in std::allocator_traits<std::allocator<int> >::deallocate(std::allocator<int>&, int*, unsigned long) ()
\#7 0x00000000004020ae in std::_Vector_base<int, std::allocator<int> >::_M_deallocate(int*, unsigned long) ()
\#8 0x0000000000401e4e in void std::vector<int, std::allocator<int> >::_M_emplace_back_aux<int const&>(int const&) ()
\#9 0x0000000000401707 in std::vector<int, std::allocator<int> >::push_back(int const&) ()
\#10 0x0000000000401212 in pushItem(int const&) ()
\#11 0x0000000000403d88 in void std::_Bind_simple<void (*(unsigned int))(int const&)>::_M_invoke<0ul>(std::_Index_tuple<0ul>) ()
\#12 0x0000000000403cd3 in std::_Bind_simple<void (*(unsigned int))(int const&)>::operator()() ()
\#13 0x0000000000403c6e in std::thread::_State_impl<std::_Bind_simple<void (*(unsigned int))(int const&)> >::_M_run() ()
\#14 0x00007f158364f5cf in ?? () from /lib64/libstdc++.so.6
\#15 0x00007f15839235ca in start_thread () from /lib64/libpthread.so.0
\#16 0x00007f1582db50ed in clone () from /lib64/libc.so.6
When i run the same program as with reserve(20) it works fine. the question is what is going on here. I assume with mutex protection also if this is happening then there is something i am missing that is inherently flawed
with vector interface itself. Kindly guide !!
#include<iostream>
#include<vector>
#include<mutex>
#include<thread>
#include<algorithm>
using namespace std;
std::vector<int> g_vector;
std::mutex g_mutex;
bool demoFlag = false;
void pushItem(const int& ref)
{
if(demoFlag)
{
cout << "Locking is enabled. so i am locking" << endl;
std::lock_guard<std::mutex> lock(g_mutex);
}
g_vector.push_back(ref);
}
int main(int argc, char* argv[])
{
if(argc == 2)
demoFlag = atoi(argv[1]);
g_vector.reserve(10);
for(unsigned int i=0; i<10; ++i)
g_vector.push_back(i);
std::vector<std::thread> threads;
for(unsigned int i=0; i<10; ++i)
threads.push_back(std::thread(pushItem,i));
std::for_each(threads.begin(), threads.end(), std::mem_fn(&std::thread::join));
for(const auto& ref : g_vector)
cout << "Item is = " << ref << " , ";
cout << endl;
}
Your lock is not be used. some code should be like this:
void pushItem(const int& ref)
{
std::lock_guard<std::mutex> lock(g_mutex);
cout << "I am locking" << endl;
g_vector.push_back(ref);
}

placement new unique pointer

It's one of my first posts. I hope it contains the correct, minimal information. Please let me know if I omitted anything.
I'm trying to use placement new to increase the efficiency of the following chunk of code (I want to reduce the number of memory allocation calls since the number_of_actions variable is large (> 500k)).
First, I am using two classes whose relationship can be summarized as:
class txn {
public:
int i;
txn(): i(0) {};
};
class ActionClass {
private:
txn* t;
public:
ActionClass(txn* t): t(t) {};
~ActionClass() { delete t; }
};
The code I was using originally to create an array of pointers to objects:
std::vector<std::unique_ptr<IBatchAction>> allocate_actions(unsigned int number_of_actions) {
std::vector<std::unique_ptr<IBatchAction>> res;
for (unsigned int i = 0; i < number_of_actions; i++) {
// construct the action
std::unique_ptr<IBatchAction> act = std::make_unique<ActionClass>(new TestTxn());
res.push_back(std::move(act));
}
return res;
}
Code after changing to use placement new:
std::vector<std::unique_ptr<IBatchAction>> allocate_actions(unsigned int number_of_actions) {
std::vector<std::unique_ptr<IBatchAction>> res(number_of_actions);
// allocate all of the memory for actions up front to amortize the cost.
ActionClass* actions =
reinterpret_cast<ActionClass*>(new char[number_of_actions * sizeof(ActionClass)]);
txn* txns = reinterpret_cast<txn*>(new char[number_of_actions * sizeof(TestTxn)]);
// use placement new to initialize actions and assign them to unique_ptrs
for (unsigned int i = 0; i < number_of_actions; i++) {
// construct the action using placement new from the memory allocated above.
res[i].reset(new(&(actions[i])) ActionClass(new(&(txns[i])) TestTxn()));
}
return res;
}
Within main.cpp I just call the above functions multiple times, time it and return 0. The vector returned from the above function is destroyed in between loop iterations. As a result I get the following stack trace just before segfault:
#0 std::unique_ptr<IBatchAction, std::default_delete<IBatchAction> >::~unique_ptr (
this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/5/bits/unique_ptr.h:236
#1 std::_Destroy<std::unique_ptr<IBatchAction, std::default_delete<IBatchAction> > > (
__pointer=<optimized out>) at /usr/include/c++/5/bits/stl_construct.h:93
#2 std::_Destroy_aux<false>::__destroy<std::unique_ptr<IBatchAction, std::default_delete<IBatchAction> >*> (__last=<optimized out>, __first=0x7ffff7f06018)
at /usr/include/c++/5/bits/stl_construct.h:103
#3 std::_Destroy<std::unique_ptr<IBatchAction, std::default_delete<IBatchAction> >*> (
__last=<optimized out>, __first=<optimized out>) at /usr/include/c++/5/bits/stl_construct.h:126
#4 std::_Destroy<std::unique_ptr<IBatchAction, std::default_delete<IBatchAction> >*, std::unique_ptr<IBatchAction, std::default_delete<IBatchAction> > > (__last=0x7ffff7fc9510,
__first=<optimized out>) at /usr/include/c++/5/bits/stl_construct.h:151
#5 std::vector<std::unique_ptr<IBatchAction, std::default_delete<IBatchAction> >, std::allocator<std::unique_ptr<IBatchAction, std::default_delete<IBatchAction> > > >::~vector (this=0x7fffffffd910,
__in_chrg=<optimized out>) at /usr/include/c++/5/bits/stl_vector.h:424
#6 time_workload_creation (exp_conf=...) at start_batch/main.cc:18
#7 0x000000000040320c in main (argc=<optimized out>, argv=<optimized out>)
at start_batch/main.cc:44
I'm new to the concept of placement new. The following is what I have used to write the above code:
Can I use placement new to reset an object within a shared_ptr? -- usage of reset to assign a new object created using placement new
placement new on shared_ptr make seg fault when delete -- a very similar problem. The answers to this one did one help me at all :(
I'm likely doing something obviously wrong, but I can't figure it out. Help? If you need the actual code from main (simplified), here it is (actions.h contains the function I have discussed).
#include "actions.h"
#include <chrono>
#include <vector>
void time_workload_creation(unsigned int act_num) {
std::chrono::system_clock::time_point time_start, time_end;
std::vector<double> results;
for (unsigned int i = 0; i < 10; i++) {
time_start = std::chrono::system_clock::now();
auto workload = allocate_actions(act_num);
time_end = std::chrono::system_clock::now();
results.push_back(
std::chrono::duration_cast<std::chrono::milliseconds>(time_end - time_start).count());
}
for (unsigned int i = 0; i < 10; i++) {
std::cout << i << "\t\t" <<
act_num << "\t\t" <<
results[i] << "\t\t" <<
act_num / results[i] << std::endl;
}
};
int main(int argc, char** argv) {
time_workload_creation(1000000);
return 0;
}
Compiled using: gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)
Code after changing to use placement new:
[...]
This code has undefined behaviour. You create an array of char using new[] and then reset N unique_ptr objects which will try to delete N different ActionClass objects. How do you expect that to work? You need to use delete[] to free the array of char, not use N delete operations on chunks of the char array.
Similarly, each ActionClass will try to delete its txn object, but that's also totally undefined, because you didn't allocate N txn objects, you allocated another array of char.
That's not how memory allocation works. You can't allocate a big chunk and then deallocate pieces of it. (Well, you can, but only by writing your own custom (de)allocation functions, or allocator).

Why am I getting this strange error when trying to add a duplicate object to a std::set?

Here is the code that is giving me trouble:
Relation* Relation::relation_union(Relation* r) {
std::set<Tuple*>::iterator it1;
for (it1 = tuples.begin(); it1 != tuples.end(); it1++) {
r->tuples.insert(*it1); //this is where i insert into the set
}
return r;
}
I can't figure out why this is happening for the life of me. I get a core dump with this code.
The following code works fine to order tuples in my set alphabetically (which are vectors of strings), but I think it's the source of my error because it doesn't know what to do when every element is the same:
EDIT Made changes to code.
struct comp {
bool operator ()(const Tuple * lt, const Tuple * rt) {
for (unsigned i = 0; i < lt->values.size(); i++) {
std::string strl = lt->values[i];
std::string strr = rt->values[i];
if (strl != strr) {
return (strl < strr); // compares with the length
}
}
return false;
}
};
'tuples' comes from the following code:
Relation(){
name = "";
schema = new Schema();
tuples = std::set<Tuple*, comp>();
domain = std::set<std::string>();
}
std::string name;
Schema* schema;
std::set<Tuple*, comp> tuples;
std::set<std::string> domain;
}
Here is my stack backtrace - it wasn't very helpful for me:
Program received signal SIGABRT, Aborted.
0x00007ffff753b425 in raise () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0 0x00007ffff753b425 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff753eb8b in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007ffff7b9169d in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff7b8f846 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff7b8f873 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff7b8f96e in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007ffff7b3c987 in std::__throw_out_of_range(char const*) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x00007ffff7b7a453 in std::string::substr(unsigned long, unsigned long) const () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#8 0x000000000040d889 in Input::getTokensValue (this=0x630460) at Input.cpp:91
#9 0x000000000040e812 in Lex::emit (this=0x7fffffffe130, tokenType=UNDEFINED) at Lex.cpp:268
#10 0x000000000040e12d in Lex::nextState (this=0x7fffffffe130) at Lex.cpp:106
#11 0x000000000040e026 in Lex::generateTokens (this=0x7fffffffe130, input=0x630460) at Lex.cpp:85
#12 0x000000000040da20 in Lex::Lex (this=0x7fffffffe130, filename=0x0) at Lex.cpp:17
#13 0x000000000040ea3e in main (argc=1, argv=0x7fffffffe248) at main.cpp:7
Any help would be much appreciated. Thanks.
bool operator ()(const Tuple * lt, const Tuple * rt) {
for (unsigned i = 0; i < lt->values.size(); i++) {
std::string strl = lt->values[i];
std::string strr = rt->values[i];
if (strl != strr) {
return (strl < strr); // compares with the length
}
}
return false;//EDIT
}
comp::operator() should return false if all values are equal.
struct comp {
bool operator ()(const Tuple * lt, const Tuple * rt) {
for (unsigned i = 0; i < lt->values.size(); i++) {
std::string strl = lt->values[i];
std::string strr = rt->values[i];
if (strl != strr) {
return (strl < strr); // compares with the length
}
}
return false;
}
};
Your comparison operator expects the 'values' member of both operands to have the same size. If rt->values is shorter than lt->values, you'll get anohter out-of-bounds error (but the one in question is not coming from here).