Recently I had a strange bug that caused a previously working C++ simulation to fail. It turned out that a logically unrelated portion of code was corrupting the memory and that corruption resulted in changing of parameter values which resulted in instability. Corruption was due to writing out of index. If that index pointed to a memory location outside the boundaries of my program I would get an access violation. Unfortunately, indices were pointing to my programs memory, therefore I did not get any errors from the operating system and had to pin point the bug by trial and error, i.e. commenting out sections of code until I got a stable state and then uncommenting until I got instability. A simplified version of the code:
#include <stdexcept> | |
void getDoubleVectorFromName(string name, double vec[MAX_FILE_NAME_LENGTH]) { | |
if (name.length() > MAX_FILE_NAME_LENGTH) { //Without this check, if string is unitialized, its length might be more than MAX_FILE_NAME_LENGTH, which might result in out of bounds writing below, leading to undefined behaviour. | |
char msg[255]; | |
sprintf(msg, "ERROR in %s, %s: name.length() (%llu) > MAX_FILE_NAME_LENGTH (%d)\n", __FILE__, __FUNCTION__, name.length(), MAX_FILE_NAME_LENGTH); | |
printf(msg); | |
throw std::invalid_argument(msg); | |
} | |
for (size_t i = 0; i < name.length(); i++) { | |
if (name[i] < 0) { | |
char msg[255]; | |
sprintf(msg, "ERROR in %s, %s: Not a valid name character code: %d at index %llu\n", __FILE__, __FUNCTION__, name[i], i); | |
printf(msg); | |
throw std::invalid_argument(msg); | |
} | |
vec[i] = name[i]; | |
} | |
for (size_t i = name.length(); i < MAX_FILE_NAME_LENGTH; i++) { | |
vec[i] = 0; | |
} | |
} |