I'm a Python kiddie looking to sharpen my CPP skills, so I did a Leetcode problem to convert integers into roman numerals. Here's the original code. Notice the lines I've marked as incorrect.
string intToRoman(int num) {
int values[] = {1000, 500, 100, 50, 10, 5, 1};
char keys[] = {'M', 'D', 'C', 'L', 'X', 'V', 'I'};
string result = "";
int current_val, digits;
for (int i = 0; i < 7; i++) {
current_val = values[i];
digits = num / current_val;
if (digits == 4 && keys[i] != 'M') { // INCORRECT LINE #1
if (result.back() == keys[i-1]) { // INCORRECT LINE #2
result[result.length() - 1] = keys[i];
result += keys[i-2];
} else { // 4
result += keys[i];
result += keys[i-1];
}
} else {
string addon(digits, keys[i]);
result += addon;
}
num %= values[i];
}
return result;
}
VScode ran this without any issues whatsoever, but when I plugged it into Leetcode, I got the following exception:
Line 1065: Char 9: runtime error: addition of unsigned offset to 0x7ffc4087c310 overflowed to 0x7ffc4087c30f (basic_string.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/basic_string.h:1074:9
After doing some research, I concluded that C++ really does not like negative indices, even when they aren't possible. So I added some checks to the incorrect lines:
if (i >= 1 && digits == 4 && keys[i] != 'M') { // CORRECT LINE #1
if (i >= 2 && result.length() >= 1 && result.back() == keys[i-1]) { // CORRECT LINE #2
The code works now, but it left me very confused. Why did my code work with one interpreter and not another? Obviously there's something I'm missing regarding how C++ compiles code. In practice, the numbers involved should never be negative. So why do I get a runtime error?