I am getting an invalid read of size 1 in the following function:
ubigint.cpp
ubigint::ubigint (unsigned long that){
//DEBUGF ('~', this << " -> " << uvalue)
ostringstream convert; // stream for converting numbers to strings
convert << that; // output the number to the stream
for(string::reverse_iterator rit = convert.str().rbegin(); rit != convert.str().rend(); rit++) // iterate through the string
{
ubig_value.push_back(*rit); // push the character
}
size_t current_size = ubig_value.size();
while(current_size != 0 && ubig_value.back() == '0')
{
ubig_value.pop_back();
current_size--;
}
}
ubigint.h
// $Id: ubigint.h,v 1.11 2016-03-24 19:43:57-07 - - $
#ifndef __UBIGINT_H__
#define __UBIGINT_H__
#include <exception>
#include <iostream>
#include <limits>
#include <utility>
using namespace std;
#include "debug.h"
#include "relops.h"
class ubigint {
friend ostream& operator<< (ostream&, const ubigint&);
private:
/*using unumber = unsigned long;
unumber uvalue {};
*/
using udigit_t = unsigned char;
using ubigvalue_t = vector<udigit_t>;
ubigvalue_t ubig_value;
public:
void multiply_by_2();
void divide_by_2();
ubigint() = default; // Need default ctor as well.
ubigint (unsigned long);
ubigint (const string&);
ubigint operator+ (const ubigint&) const;
ubigint operator- (const ubigint&) const;
ubigint operator* (const ubigint&) const;
ubigint operator/ (const ubigint&)const;
ubigint operator% (const ubigint&) const;
bool operator== (const ubigint&) const;
bool operator< (const ubigint&) const;
//helper functions
string vectorToString(ubigvalue_t& myVector)const;
};
#endif
Error Message:
==4025== Invalid read of size 1
==4025== at 0x40309C: ubigint::ubigint(unsigned long) (ubigint.cpp:23)
==4025== by 0x40412F: udivide(ubigint const&, ubigint) (ubigint.cpp:260)
==4025== by 0x404418: ubigint::operator/(ubigint const&) const (ubigint.cpp:285)
==4025== by 0x40709D: bigint::operator/(bigint const&) const (bigint.cpp:89)
==4025== by 0x40CCEB: do_arith(iterstack<bigint>&, char) (main.cpp:35)
==4025== by 0x40D58F: main (main.cpp:143)
I didn't put the other functions because I think that the cause of the problem is the constructor. I noticed that I was comparing ubig_value.back() against the integer 0. I changed it to char and that still didn't solve the problem. What is wrong with the constructor?. Line 23 is ubig_value.pop_back();. When I run the program without using valgrind, it runs properly.
convert.str()
returns a temporary string
instance, by value. Two calls to convert.str()
produce different instances of string
, so convert.str().rbegin()
and convert.str().rend()
do not form a valid range - they are iterators into different containers.
Moreover, rit
is a dangling iterator - the string it points into, being a temporary, is gone by the time the iterator is used.
Therefore, your function exhibits undefined behavior.