Wednesday, August 31, 2022

[SOLVED] Better runtime error in C++ for vectors and address boundary error

Issue

In Python, when we access an index out of the array range we get an error output that gives the exact location in the code that had this error:

array = []
index =  0
array[index]
IndexError                                Traceback (most recent call last)
Untitled-1 in <cell line: 3>()
      1 array = []
      2 index =  0
----> 3 array[index]

IndexError: list index out of range

But a code like this in C++ only gives us a generic address boundary error in both GCC and Clang compiler:

#include <vector>

int main(int argc, const char **argv) {
  std::vector<int> array{};
  int index = 0;
  int value = array[index];

  return 0;
}

Is there a way to have better runtime errors with more detail in C++??


Solution

only give us a generic Address boundary error

No, it isn't even guaranteed to do that. Accessing out-of-bounds with [] causes undefined behavior in C++. If it happens you loose any guarantee on the program's behavior. It may fail with some kind of error, but it might also just continue running producing wrong output or do anything else. This is a very important difference from Python that must be understood. In C++ if you violate language rules or preconditions of library functions there is no guarantee that the compiler or the program will tell you about it. It will just not behave as expected in many cases.

To figure out where such an error comes from you usually run your program under a debugger which will tell you the line that e.g. a segmentation fault (if one happened) occurred and allows you to step through the code.

You can guarantee that indexing a std::vector out-of-bounds will generate an error message by using its .at member function instead of indexing with brackets. If the index is then out-of-bounds an exception will be thrown which you can catch or let propagate out of main to terminate the program with some error message. However, the exception doesn't typically carry information about the point at which it was thrown. Again you'll need to run under a debugger to get that information.

Depending on your compiler and platform, if you keep using [], you may also be able to compile your program with a sanitizer enabled which will print a diagnostic including source lines when such an out-of-bounds access occurs. For example GCC and Clang have the address sanitizer which can be enabled with -fsanitize=address at compile-time. The option -g should be added as well to generate debug symbols that will be used in the sanitizer output to reference the source locations.



Answered By - user17732522
Answer Checked By - Marie Seifert (WPSolving Admin)