Is it possible see the value returned in c++? - c++

So..I'm testing a function with assert: (The value of pBola1 is 1)
assert(BomboTest.TreureBola(1)==pBola1);
BomboTest.TreureBola it's a function that returns a random number (in this case has to return 1) of a list.
cBola* cBombo::TreureBola(int num)
{
int posicio_aleatoria;
posicio_aleatoria= rand() % (num);
return(Boles.TreureElement(posicio_aleatoria));
}
And TreureElement it's a function that returns an element of a dynamic list knowing the position of the element that you want to extract(in this case returns 'retorn' which is 1)
cBola* cLlista::TreureElement(int posicio)
{
int i;
cBola* recorreLlista;
cBola *retorn;
recorreLlista=primer;
retorn = primer;
i=0;
if (posicio == 0)
{
primer = (*primer).getSeguent();
}
else
{
// Busquem la posiciĆ³ //
while(i < posicio)
{
recorreLlista= retorn;
retorn = (*retorn).getSeguent();
i++;
}
(*recorreLlista).setSeguent( (*retorn).getSeguent() );
}
numElements--;
return retorn;
}
And I don't know why but the assert fails. I can see the value returned by TreureElement because I have the pointer 'retorn' but I can't know the value returned by TreureBola..There is some way to see that value returned by TreureBola in the debugger?
PD:I'm using visual studio 2010

Just create a local
cBola* pTemp = BomboTest.TreureBola(1);
assert(pTemp==pBola1);
You could look in the dissasembly and inspect the return registry, but this seems like overkill. The above is the correct approach and others will thank you in the future, when they encounter the same problem.

You can always temporarily change
assert(BomboTest.TreureBola(1)==pBola1);
to`
auto tmp=BomboTest.TreureBola(1);
assert(tmp==pBola1);
and place a breakpoint on the first line.

I would write a small wrapper around assert to use instead:
template <typename T>
void compare(const T& lhs, const T& rhs)
{
if (lhs != rhs)
cout << "The values were not the same! " << lhs << " vs. " << rhs << endl;
assert(lhs == rhs);
}
This will still call assert, but first you'll get some (hopefully) useful output first.
So instead of calling:
assert(BomboTest.TreureBola(1)==pBola1);
You would call:
compare(BomboTest.TreureBola(1), pBola1);
This has an added benefit that you can place a breakpoint here and see see what TreureBola returned in the debugger, too.

Related

C++ There is a bool return type function returning (24) here

First of all sorry for too much code
Here there is a vector (teamNum) with type class, the class contain a vector (player) with type struct, it is a little complicated, but here in this function I need to check if there is a player in teamNum which contain tName equal to _tname (function parameter) contain (the player) pID equal to _pID (function parameter)
bool thereIsSimilarID(string _tname, int _pID)
{
for (int i = 0; i < teamNum.size(); i++)
{
if (teamNum[i].tName == _tname)
{
for (int j = 0; j < teamNum[i].player.size(); j++)
{
if (teamNum[i].player[j].pID == _pID)
return true;
}
}
else if (i == (teamNum.size() - 1))
{
return false;
}
}
}
And in the main
int main()
{
cout << "\n" << thereIsSimilarID("Leverpool", 1) << endl;
}
The output is 24 !!!!!
(good note that this happen just when the team (Leverpool) is the last team in the vector teamNum)
Again sorry for too much code but I need to know the bug not only fix the problem I need to learn from you
You encountered undefined behaviour.
If you take the if (teamNum[i].tName == _tname)-branch on the last element, but find no player with the correct pID, you don't return anything. Which means, that the return value is whatever random value is currently in the memory location that should hold the return value. In your case it happens to 24. But theoretically, everything could happen.
The same problem occurs when teamNum is empty.
The solution is to make sure to always return a value from a function (except if it has return type void of course):
bool thereIsSimilarID(string _tname, int _pID)
{
for (int i = 0; i < teamNum.size(); i++)
{
// In this loop return true if you find a matching element
}
// If no matching element was found we reach this point and make sure to return a value
return false;
}
You should take a look at your compiler settings and enable all the warnings. And often it's good to let it treat certain warnings as errors.

Generic variable to store varying levels of pointers

I want to write a generic centralized null-checker API for pointer type objects. I want to populate a list of my input pointer objects and call the null-checker API to scan through the list and validate if any pointer object is having NULL value. For this, I need to store varying levels of pointers in a single generic variable. How can I do that in C++ ?
template<typename type>
bool check(type& t)
{
return false;
}
template<typename type>
bool check(type* t)
{
return true;
}
int main()
{
char** doubleCharPointer = NULL;
char* charPointer = "charPointer";
doubleCharPointer = &charPointer;
char** temp = doubleCharPointer;
char* temp1 = NULL;
int count = 0;
if(!check(temp))
{
cout << "\nNot a pointer" << endl;
return 0;
}
temp1 = *temp;
count++;
if(!check(temp1))
{
cout << "\nPointer level : " << count << endl;
return 0;
}
count++;
cout << "\nPointer level : " << count << endl;
}
This is my null-checker prototype. It is very static at the moment. But I wanted to extend it to support any level of pointer checking. For that I need "temp" to be able to hold any level of pointer so that I can run an infinite while loop till all the levels of the input pointer is consumed and validated. How can I do that ? Please help.
I don't believe that there is a direct solution to this without knowing the exact numbers of levels. Let's say that you can advance level by level checking every level if it's NULL or not, however the main problem is that you don't know how far you must search, so in the end if you just go from address to address you may end up finding a NULL pointer or never ending your verification loop because you don't have a stop condition.
By doing this you may also access an unallocated memory address which may throw or not an exception, so you can't either use this thrown exception as a stop condition.
I think you want
template<typename T>
bool check_ptr_not_null(const T&)
{
return true; // not a pointer
}
template<typename T>
bool check_ptr_not_null(T* t)
{
return (t != nullptr) && check_ptr_not_null(*t);
}
Live Demo
Disclaimer: Do not up-vote this answer (dirty hack)
Expanding on A-B's answer, this is the best I can get to at the moment:
template<typename T>
bool notnull(T const *t, int level) {
while (level-- > 1) {
if (t == NULL)
return false;
t = (T const *)*t;
}
return t != NULL;
}
Note that this will induce some compiler warnings because of the line t = (T const *)*t so I guess this is unsafe. A cleaner way of doing this is just define some macros instead:
#define NOTNULL_P1(x) (x != NULL)
#define NOTNULL_P2(x) ((x != NULL) && NOTNULL_P1(*x))
#define NOTNULL_P3(x) ((x != NULL) && NOTNULL_P2(*x))
#define NOTNULL_P4(x) ((x != NULL) && NOTNULL_P3(*x))
#define NOTNULL_P5(x) ((x != NULL) && NOTNULL_P4(*x))

Segmentation Fault while comparing strings

In my program, there is a part where i need to sort an array of struct.
Everything goes nice until the end i think.
For some entries everything is nice and works until some entries at the end of the array.
There it throws a segmentation fault and i don't know why.
struct overview_table{
string o_timestamp;
string n_timestamp;
string dbID;
};
sort(overview.begin(),overview.end(),compareStrings);
static bool compareStrings(const overview_table &a_timestamp, const overview_table &b_timestamp){
cout << "744" << endl;
if ( a_timestamp.n_timestamp.compare(b_timestamp.n_timestamp) <= 0){
cout << "746" << endl;
return true;
} else {
cout << "749" << endl;
return false;
}
}
For information: the output was only to check where the segmentation fault is thrown. And it is between 744 and 746 and how i think at the end of the array. But i don't know why
If i'm not wrong, to sort 2 structs you have to compare the whole struct, not only a field. And you're comparing only the n_timestamp field. Second, you don't put <= in the comparison but just < or >.
This is an example of an operator overload:
bool operator<(const overview_table &a, const overview_table &b)
{
if ( a.n_timestamp.compare(b.n_timestamp) < 0) {return true;}
if ( a.n_timestamp.compare(b.n_timestamp) > 0) {return false;}
if ( a.o_timestamp.compare(b.o_timestamp) < 0) {return true;}
if ( a.o_timestamp.compare(b.o_timestamp) > 0) {return false;}
return a.dbID.compare(b.dbID);
}
hope this helps. Pleas ask if I was not clear!
The compare function shall satisfy the principle of weak ordering.
Change the function the following way
static bool compareStrings( const overview_table &a_timestamp,
const overview_table &b_timestamp )
{
return a_timestamp.n_timestamp < b_timestamp.n_timestamp;
}
A little more source would be nice...
But first of all: compare should return 0 in case of equality, so your
if ( a_timestamp.n_timestamp.compare(b_timestamp.n_timestamp) <= 0)
doesn't make any sense... Otherwise (if it's intended) your function's name is misleading.
To figure out, where your segmentation fault comes from, we need to see more sourcecode, but Segmentation faults indicate, that you are trying to acces nestet values from a null pointer, so in your case it seems, that one of your compared structs was never created...
Which could and should be checked by a if (null == x) return false; or something like that

dynamic_bitset, crash my program

I'm new with boost. I have a program which uses dynamic_bitset inside a lambda function. After I try to run the program, I get this message. This message appears even without the function that initializes the bitset and the functions that handle it.
Does anybody know what this message means and what might be the problem?
The message:
/usr/include/boost/dynamic_bitset/dynamic_bitset.hpp:616: boost::dynamic_bitset<Block, Allocator>::~dynamic_bitset() [with Block = long unsigned int, Allocator = std::allocator<long unsigned int>]: Assertion 'm_check_invariants()' failed.
Aborted
well the code is something like this
main call to this function :
int Molecule::initSimilarity(int depth){
cout << "_size is: " << _size << "\t depth is: " << depth << endl; //TODO delete
AtomSet viewing(_size);
int m = 0;
{
// break into initial groups by symbol and valancy
for(int i=0 ; i<_size ; i++)
{
if(viewing[i]) continue;
AtomSet mask = getSetMask( //AtomSet is typedef for dynamic_bitset
[&](const Atom& b)->bool
{
return (!viewing[b._index] && b._valence == _atoms[i]->_valence && strcmp(b._symbol, _atoms[i]->_symbol) == 0);
},
[&](Atom &b)
{
b._class = m; //set the equivalence class of atom 'b' to 'm'
}
);
m++;
viewing |= mask; //viewing now contains a set of atoms and for each atom it's equivalence class
}
cout << "number of equivalence class: " << m << endl; //TODO DELETE!
}
for (int j = 0; j < depth ; j++){
AtomSet viewed(_size);
int before = m;
// iteratively refine the breakdown into groups
for (int i = 0 ; i < _size ; i++) //for any atom A
{
if (viewed[i]) continue;
viewed.flip(i);
AtomSet mask = getSetMask(//put all atoms which are equivalnt but not similar to A in
//their own equivalence class
[&](const Atom& b)->bool
{
if (viewed[b._index])
return false; //if b is in viewed return false;
if (_atoms[i]->_class == b._class) //if in the same class add b to viewed
{
viewed.flip(b._index);
bool similar = !isSimilar(*_atoms[i],b);
return similar;
}
return false;
},
[&m](Atom& b)
{
b._class = m;
}
);
if (!mask.none()) m++;
}
if (before == m){
std::cout << "Finished early after just " << j << " iterations" << std::endl;
return m;
}
}
return m;
}
the signature of getSetMask is:
AtomSet getSetMask(std::function property, std::function action);
and the weirdest thing that even when i remove all the content of that function it still give me the error message
Probably the dynamic_bitset variable that you are referencing in the lambda has gone out of scope and has already been destroyed, or something similar. (Without the source code it's difficult to be more specific)
I had that problem and it took me 3 hours to find out the problem. Here is what can happen: The operator[] in dynamic_bitset does not do bound checking. So, one value can be assigned outside of allowed range and this does not create any error (sanitizer/valgrind do not see anything) since dynamic_bitset is using 64 bit integers (on my computer at least) in order to store values. So, you can get a stored integer of 32 while you allowed only 4 bits in the dynamic_bitset. The error is triggered at a later time when m_check_invariant() is called for example when the destructor is called.
So, the problem becomes to find this range error. The solution is to edit the boost/dynamic_bitset.hpp and add print statement in the code of operator[] when an operation out of range is called. If you cannot do that then download the boost library and install it in your home directory.
I had a similar problem with dynamic_bitset that was solved by calling reset() on it before it got destroyed.
That can indicate that you are writing past the end of the bitset without resizing it. Might want to do some bounds checking.
Read the explaination of Mathieu Dutour Sikiric. The problem is that you write outside of allowed range of the bitset via operator[] and this does not create any error because it's boost and it doesn't bother to waste compute time checking that you have right to write where you want. It is C++ you know...
So to detect it, go to boost/dynamic_bitset/dynamic_bitset.hpp, and modify the code to impose checks every time you use operator[].
boost/dynamic_bitset/dynamic_bitset.hpp, around line 300.
reference operator[](size_type pos) {
assert(m_check_invariants());
return reference(m_bits[block_index(pos)], bit_index(pos));
}
bool operator[](size_type pos) const {
assert(m_check_invariants());
return test(pos);
}
This makes it easier to detect the error in your code.

Assigning Private Variable within a constructor

I've read through stack overflow threads multiple times in the past, and they're often quite helpful. However, I've run into a problem that simply doesn't make sense to me, and I'm trying to figure out what I missed. Here's the sections of the code that I'm having trouble with:
class BigInts
{
public:
static const std::size_t MAXLEN = 100;
BigInts(signed int i); //constructor
BigInts(std::string &); //other constructor
std::size_t size() const;
digit_type operator[](std::size_t ) const;
private:
digit_type _data[MAXLEN];
bool _negative;
int _significant;
};
//nonmember functions
std::ostream & operator << (std::ostream &, const BigInts &);
BigInts::BigInts(signed int i)
{
_negative = (i < 0);
if (i < 0)
{
i = -1*i;
}
std::fill(_data, _data+MAXLEN, 0);
if (i != 0)
{
int d(0);
int c(0);
do
{
_data[d++] = ( i % 10);
i = i / 10;
c++; //digit counter
}while(i > 0);
//_significant = c; //The problem line
assert(c <= MAXLEN); //checks if int got too big
}
}
std::size_t BigInts::size() const
{
std::size_t pos(MAXLEN-1);
while (pos > 0 && _data[pos] == 0)
--pos;
return pos+1;
}
std::ostream & operator << (std::ostream & os, const BigInts & b)
{
for (int i = (b.size() - 1); i >= 0; --i)
os << b[i];
return os;
}
int main()
{
signed int a, b;
std::cout << "enter first number" << std::endl;
std::cin >> a;
std::cout << "enter second number" << std::endl;
std::cin >> b;
BigInts d(a), e(b), f(b);
std::cout << d << " " << e << " " << f;
Major edit, switched from an attempted dummy version of the code to the actual code I'm using, complete with the original variable names. I tried to remove anything that isn't relevant to the code I'm currently working with, but if you see a strange name or call in there, let me know and I can post the associated portion.
The code had been working fine prior to the introduction of _significant, which is a variable I had added to add some more functionality to the class as a whole. However, when I attempted to drive the basic parts of it using the main function you see displayed, it encountered large errors. For example, I inputted 200 and 100 for a and b respectively, it outputted 201, 1, and 3 for d, e, and f. As it currently stands, the ONLY place _significant appears is when I'm attempting to assign the value of c to it.
The only error I can see right now is that _significant isn't initialized when the input is zero.
Step through it in a debugger, make sure the the right digits are ending up in the array and that the array data isn't being overwritten unexpectedly.
EDIT: It works for me (cleaned up slightly). More cleaned up, also working: http://ideone.com/MDQF8
If your class is busted purely by assigning to a member variable, that means stack corruption without a doubt. Whilst I can't see the source offhand, you should replace all buffers with self-length-checking classes to verify accesses.
The line i - 1; in the original code looks highly suspicious. Did you want to write i -= 1; or --i; or something else?
It decrements i by 1 and then throws away the result.