Недавно я прочитал, что подписанное целочисленное переполнение в C и С++ вызывает поведение undefined:
Если во время оценки выражения результат не определен математически или нет в диапазоне отображаемых значений для его типа, поведение undefined.
В настоящее время я пытаюсь понять причину поведения undefined. Я думал, что здесь происходит поведение undefined, потому что целое число начинает манипулировать памятью вокруг себя, когда оно становится слишком большим, чтобы соответствовать базовому типу.
Итак, я решил написать небольшую тестовую программу в Visual Studio 2015, чтобы проверить эту теорию следующим кодом:
#include <stdio.h>
#include <limits.h>
struct TestStruct
{
char pad1[50];
int testVal;
char pad2[50];
};
int main()
{
TestStruct test;
memset(&test, 0, sizeof(test));
for (test.testVal = 0; ; test.testVal++)
{
if (test.testVal == INT_MAX)
printf("Overflowing\r\n");
}
return 0;
}
Я использовал здесь структуру, чтобы предотвратить любые защитные функции Visual Studio в режиме отладки, такие как временное дополнение переменных стека и т.д.
Бесконечный цикл должен вызывать несколько переполнений test.testVal
, и это действительно так, хотя и без каких-либо последствий, кроме самого переполнения.
Я просмотрел дамп памяти во время выполнения тестов переполнения со следующим результатом (test.testVal
имел адрес памяти 0x001CFAFC
):
0x001CFAE5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x001CFAFC 94 53 ca d8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Как вы видите, память вокруг int, которая постоянно переполняется, осталась "неповрежденной". Я тестировал это несколько раз с аналогичным выходом. Никогда не было памяти вокруг переполненного внутреннего повреждения.
Что здесь происходит? Почему нет повреждений для памяти вокруг переменной test.testVal
? Как это может привести к поведению undefined?
Я пытаюсь понять свою ошибку и почему нет повреждения памяти во время переполнения целых чисел.