C++ runtime errors

From ODF::Wiki

Jump to: navigation, search

This site shall collect our members' experience to show users examples of issues with C++ coding. Here, in particular, only runtime errors (i.e. errors that are not recognized by the compiler, but cause incorrect behavior when the code is executed) are collected.

NOTE! Before you look for an error here, it is suggested to run valgrind. Some valgrind errors can be looked up in the valgrind errors article.

Contents

[edit] Debugging output missing

If you made a debugging output in a code that just does not show, consider the most easy solutions (which happen *very* often):

  • Your editor did not save the new version of the source file, you forgot to compile the program/library or (on linux) you set the library path wrong (on linux, type LD_LIBRARY_PATH=/path/to/newer/version/of/my/library/ into your shell before debugging)
  • You made the output after a throw or a return, exit(), pthread_exit() or a similar function
  • You did not terminate the call of printf()/cout/whatever with a newline ('\n'). Many computer systems don't print any output before a newline is sent to a IO buffer (this is called buffered)

[edit] Iterators

[edit] Removing Iterators in a loop (stl list)

Let's have a look at the following code, that shall remove all integers equal to 42 out of a list:

void func(list<int>& intlist)
{
    for(list<int>::iterator itr = intlist.begin(); itr!=intlist.end(); itr++)
     if(*itr == 42)
      itr=list.erase(itr);
}

What's so wrong about it? You will notice that, if a 42 is followed by another 42, only the first 42 is erased. Why? The code

itr=list.erase(itr)

erases the element handled by itr out of the list. To not lose the position, the function returns an iterator to the next element. However, the next for loop will increase itr, again (due to the "itr++" in the for line).

How can this problem be solved? Here is an example:

void func(list<int>& intlist)
{
    for(list<int>::iterator itr = intlist.begin(); itr!=intlist.end();)
    {
        if(*itr == 42)
         itr=list.erase(itr);
        else itr++;
    }
}

The only thing we did is removing the itr++ out of the for line and inserting the line "else itr++".

[edit] Removing Iterators in a loop (stl map)

The situation is getting more complicated using maps, because the erase command does not return an iterator to the element which takes place of the one you just removed! The reason therefore is simple: Where should that pointer point to? To the left branch or to the right branch? Does it even exist after re-balancing? Yes, trees are much more complicated then lists...!

A solution is back-upping the iterator, then increasing it and, finally, erase the backup:

void func(map<int>& intmap)
{
    for(map<int, int>::iterator itr = intmap.begin(); itr != intmap.end();) {
        if(itr->first == 42) {
            map<int, int>::iterator erase_element = itr++;
            growing_files.erase(erase_element);
        }
        else 
         itr++;
    }
}

[edit] Databases

[edit] Troubles with SQLite

If you are using SQLite instead of mySQL, lots of queries may fail! Here is a list which gives reasons for that:

  • You forgot the semicolon at the end!
  • If you use QSQLITE, the query.size() is usually -1, however, you can still iterate checking query.next()
  • Does the database (=file) you want to use already exist? If yes, is it in the correct version?
Personal tools