DWORD DecimalBaseAddr = GetModuleBase (gameName, pID);
cout << "The Base Address is: " << DecimalBaseAddr << "n";
vector<DWORD> pointsOffsets{ 0x1700, 0x0, 0x10, 0x8, 0x988 };
DWORD WorldPtr = 0x258C9D0;
DWORD WorldAddr = NULL;
ReadProcessMemory(pHandle, (LPVOID)(DecimalBaseAddr+ WorldPtr), &WorldAddr, sizeof(WorldAddr), NULL);
cout << WorldAddr << "n";
DWORD pointsAddr = WorldAddr;
for (int i = 0; i < pointsOffsets.size() - 1; i++) {
ReadProcessMemory(pHandle, (LPVOID)(pointsAddr+ pointsOffsets.at(i)), &pointsAddr, sizeof(pointsAddr), NULL);
cout << "Value at the offset is = " << hex << pointsAddr << "n";
}
pointsAddr += pointsOffsets.at(pointsOffsets.size() - 1);
Не знаю где здесь моя ошибка, однако когда DecimalBaseAddr = e6910000
, то при сложении в строке :
ReadProcessMemory(pHandle, (LPVOID)(DecimalBaseAddr+ WorldPtr), &WorldAddr, sizeof(WorldAddr), NULL);
cout выводит 0, и все последующие оффсеты (Я сейчас говорю про цикл ниже)
for (int i = 0; i < pointsOffsets.size() - 1; i++) {
ReadProcessMemory(pHandle, (LPVOID)(pointsAddr+ pointsOffsets.at(i)), &pointsAddr, sizeof(pointsAddr), NULL);
cout << "Value at the offset is = " << hex << pointsAddr << "n";
}
Так вот весь цикл тоже выводит 0, плюс в обоих случаях висит предупреждение C26451. Я не знаю, как и что исправить, чтобы предупреждение исчезло, а операторы работали нормально.
!!! UPD !!!
Ошибку с Арифметическим переполнением удалось решить, однако все остальные ReadProcessMemory() выводят 0. Посмотрел GetLastError() — выводит ошибку 12b, то есть ReadProcessMemory() выполняется не полностью, в чем может быть ошибка?
Battary 7 / 6 / 1 Регистрация: 29.10.2016 Сообщений: 175 |
||||||||||||
1 |
||||||||||||
Арифметическое переполнение27.01.2020, 18:33. Показов 31142. Ответов 4 Метки нет (Все метки)
Доброго всем времени суток! Никак не могу решить проблему с этим: Кликните здесь для просмотра всего текста
C26451 Арифметическое переполнение: использование оператора «-» на байтовом значении 4 и приведение результата к байтовому значению 8. Приведите значение к более широкому типу перед вызовом оператора «-«, чтобы избежать переполнения (io.2). Собственно почему? Я же прибавляю 4байтовый int (1) к 4байтовому j. Функция
Класс
Main
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
27.01.2020, 18:33 |
Ответы с готовыми решениями: Переполнение Переполнение void menu() Переполнение Exception переполнение 4 |
6576 / 4561 / 1843 Регистрация: 07.05.2019 Сообщений: 13,726 |
|
27.01.2020, 19:08 |
2 |
Я в курсе, что возвращаемое значение метода .size() не int, а size_t, но ни замена int на size_t в for, ни приведение к int не решают эту проблему. Как можно решать это? Используй size_t в обоих циклах, для i и для j. Зачем тебе там int?
0 |
7 / 6 / 1 Регистрация: 29.10.2016 Сообщений: 175 |
|
27.01.2020, 20:07 [ТС] |
3 |
Используй size_t в обоих циклах, для i и для j. Зачем тебе там int? Я пробовал, ошибка не уходит. А int там нужен, потому что массив не больше 1000.
0 |
6576 / 4561 / 1843 Регистрация: 07.05.2019 Сообщений: 13,726 |
|
27.01.2020, 21:10 |
4 |
Сообщение было отмечено Battary как решение Решение
Я пробовал, ошибка не уходит. А int там нужен, потому что массив не больше 1000. Во-первых, это не ошибка, а предупреждение, в принципе можно забить.
0 |
большой ДЕН 1 / 1 / 0 Регистрация: 01.05.2017 Сообщений: 144 |
||||
26.09.2020, 19:15 |
5 |
|||
Привет.
Выражение «(k — 1)» подчеркнутос предупреждением «c26451 арифметическое переполнение использование оператора «-» на байтовом значении 4 и приведение результата к байтовому значению 8″
0 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
26.09.2020, 19:15 |
Помогаю со студенческими работами здесь Задача на переполнение Переполнение стека Переполнение double как отловить переполнение при расчетах double; double db =… Переполнение буфера int… Искать еще темы с ответами Или воспользуйтесь поиском по форуму: 5 |
The difference (in both of subtractions) can result in overflow. The overflow may happen if you subtract negative values from positive, or positive values from negative.
For example, if you subtract something negative from a maximum possible value, you’ll get an overflow.
As you have wider destination type, it is possible that you intend this wider result to fit this wider type without overflow. This will not happen, unless you cast one of your operands.
I don’t think it is practical to do such cast here, as you use %
operator, this will not work with double
. And anyway it will not handle overflow, just because you cannot have more range here than range of rand()
.
Apparently if you want to fix the possible overflow of rand()
, you’ll need std::uniform_int_distribution
with your range. This would fix other rand()
problems along (thread safety and not good randomness), but would add a bit of complexity as well.
But sure if you always have -30 to 50 range, there’s no overflow, and you can treat it as a false warning. If you literally have int max = 50, min = -30;
I even see it as a bug of static analysis to emit this warning. Sure static analysis cannot predict the result of rand()
, but there’s %
to truncate it. Maybe use Help > Send Feedback > Report a problem if you care.
Как устранить эти предупреждения?
// midiNote is a double as it is used in floating point equation
// v is int because that's informative that the function wants whole numbers
void setMidiNote(int v) { midiNote = v-48; }
Предупреждение C26451 Арифметическое переполнение: использование оператора ‘-‘ для 4-байтового значения и последующее приведение результата к 8-байтовому значению. Перед вызовом оператора ‘-‘ приведите значение к более широкому типу, чтобы избежать переполнения (io.2).
// input should be 0 to 10 integer, and dank will be odd integers only
// dank is a double, it is ultimately used in a floating point equation
void setDarkIntensity(int v) { dank = v * 2 + 1; }
Предупреждение C26451 Арифметическое переполнение: использование оператора ‘*’ для 4-байтового значения и последующее преобразование результата к 8-байтовому значению. Перед вызовом оператора ‘*’ приведите значение к более широкому типу, чтобы избежать переполнения (io.2).
Предупреждение C26451 Арифметическое переполнение: использование оператора ‘+’ для 4-байтового значения и последующее приведение результата к 8-байтовому значению. Приведите значение к более широкому типу перед вызовом оператора ‘+’, чтобы избежать переполнения (io.2).
7 ответов
Предупреждения говорят вам, что существует вероятность того, что ваши вычисления переполнят исходный (меньший) тип перед преобразованием в результат (больший) тип. В первом случае, если v
равно MIN_INT (-2 31 ), вычитание опустится, что приведет к неопределенному поведению (вероятно, большое положительное число), которое затем будет сохранено в midiNote
. Чтобы избежать предупреждения, сначала конвертируйте в более крупный тип:
midiNote = double(v) - 48;
Аналогично вашему второму примеру.
Хотя вы можете знать, что setMidiNote
не будет вызываться со значениями, которые будут иметь эту проблему, компилятор не знает и выдает это предупреждение, чтобы предупредить вас о возможности возникновения проблемы.
7
1201ProgramAlarm
5 Май 2019 в 22:58
Я считаю, что это ошибка VS2019. Он больше не отмечен в VS2022.
Например, это вызывает предупреждение
double test2(int n)
{
return 4.0 * (n - 1);
}
Но это не так
int test2a(int n)
{
return 4 * (n - 1);
}
Однако для последнего риск неопределенного поведения намного выше. Умножение на 4 значительно увеличивает риск UB, поскольку очень большой набор n даст UB. Как здорово? Что ж, есть только одно возможное значение n
из примерно 4 миллиардов возможных значений в первом примере, которое переполняется. Во втором есть около 3 миллиардов n
, которые могут быть переполнены / не заполнены. Почему? Потому что целочисленная арифметика была бы невозможна, если бы каждое выражение с большей сложностью, чем добавление 0 или умножение на 1, было помечено, потому что оно могло переполняться.
Вероятно, для такого высокого значения предупреждения будет предупреждена практически любая арифметическая операция с целыми числами.
Этот ответ показывает способ отключить это предупреждение в VS 2019 в редакторе набора правил анализа кода.
Предупреждение C26454: арифметическое переполнение: операция ‘-‘ дает отрицательный результат без знака во время компиляции (io.5)
Однако Microsoft, начиная с VS2022, больше не выдает предупреждение C26451 в виде волнистой линии для этого. И не отображается под -Wall. Видимо, они увидели свет.
19
doug
15 Дек 2021 в 06:56
Я решил проблему, посмотрев на Microsoft Docs, но вы также можете изменить свой переменная в тип long long
(я знаю, сверху). Это избавило меня от ошибок. Надеюсь, они скоро займутся этим.
3
KoalaZub
2 Янв 2020 в 16:30
Я избавился от предупреждения, изменив тип переменной на «unsigned __int64». Это то, что предлагает сообщество разработчиков Microsoft!
3
passionateProgrammer
2 Май 2020 в 19:57
Static_cast<>() является рекомендуемым решением. В книге, которую я сейчас читаю, большое внимание уделяется этому новому соглашению о приведении типов. Простое использование (v) считается стилем C.. (Согласно литературе). .Интересно.. сработает ли просто объявить v как auto. Похоже, Вектор что-то замышляет…
Недействительным setDarkIntensity (авто v) { сырой = v * 2 + 1; }
0
George Abraham
3 Авг 2022 в 20:03
Приведите тип данных, который вы хотите, как можно раньше, а затем используйте его полностью:
// midiNote is a double as it is used in floating point equation
// v is int because that's informative that the function wants whole numbers
void setMidiNote(int v) { midiNote = static_cast<double>(v) - 48.0; }
// input should be 0 to 10 integer, and dank will be odd integers only
// dank is a double, it is ultimately used in a floating point equation
void setDarkIntensity(int v) { dank = static_cast<double>(v) * 2.0 + 1.0; }
Раньше считалось, что операции с целыми числами выполняются намного быстрее, чем операции с плавающей запятой, но это уже не так для современных процессоров.
Использование 2.0
вместо 2
приводит к неявному приведению v
к double
, но явное приведение всегда более понятно.
Дополнительный совет: рассмотрите возможность проверки любых предположений в отладочных сборках. Это поможет избежать нарушения этих предположений при изменении кода в будущем. Что-то типа:
// input should be 0 to 10 integer, and dank will be odd integers only
// dank is a double, it is ultimately used in a floating point equation
void setDarkIntensity(int v)
{
assert(v >= 0 && v <= 10);
dank = static_cast<double>(v) * 2.0 + 1.0;
}
Дополнительный совет 2: если эти функции не являются частью класса, я бы назвал их inline
, чтобы у оптимизатора было больше шансов справиться с этими простыми функциями. Если они являются частью определения класса, то это уже сделано неявно.
0
Darrin Cullop
5 Авг 2022 в 20:00
#c #visual-studio #qt #c 17 #overflow
#c #visual-studio #qt #c 17 #целое число-переполнение
Вопрос:
Я работаю в Visual Studio Community 2019 и получаю предупреждение о переполнении C26451: Arithmetic при использовании знака минус внутри оператора [] вектора. Мой код:
std::vector<int> cx;
// code to fill cx
// iStrt and iCnst are constant iterators and pData is my data vector
for (int ii = 1; ii < cx.size(); ii) {
if (cx[ii - 1] < 0) // C26451: Arithmetic Overflow
iStrt = pData.cbegin();
else
iStrt = iCnst cx[ii - 1]; // C26451: Arithmetic Overflow
}
Все предупреждение:
C26451: Арифметическое переполнение: использование оператора ‘-‘ для 4-байтового значения с последующим преобразованием результата в 8-байтовое значение. Приведите значение к более широкому типу перед вызовом operator ‘-‘, чтобы избежать переполнения
Почему появляется предупреждение, когда все, что я делаю, — это простое вычитание целого числа?
Добавление после комментариев:
Вся функция слишком длинная и сложная, чтобы публиковать ее здесь. Основная задача функции заключается в преобразовании точек данных в std::vector<double> pData
координатах экрана. То, что я опубликовал выше, более или менее совпадает с приведенным ниже. Приведенный ниже код содержит дополнительные пояснения. Это основная часть моей функции, я думаю, она должна быть воспроизводимой.
void UPlot::plotData()
{
// This vector contains indexes for data plotting
// i.e. pData[cx[1]] - pData[cx[0]] will be plotted
// in a single column of pixels
std::vector<int> cx;
// constant values:
// w_ = width in pixels (e.g. 500)
// lft_ = Start data index (e.g. 150)
// rit_ = End data index (e.g. 10000)
// xFact_ = (rit_ - lft_) / w_ i.e. translation factor
for(int ii = 0; ii < (w_ 1); ii)
cx.push_back(round(lft_ (ii * xFact_)));
// since the difference between cx[ii] - cx[ii-1] is
// required, cx has to be greater than 1
if (cx.size() > 1) {
iCnst = pData.cbegin();
// iterate over cx and find out the number of data points
// that will be plotted in a single column of pixels
for (int ii = 1; ii < cx.size(); ii) {
if (cx[ii] < 0)
continue; // only ve indexes can work
else if (cx[ii - 1] >= pData.size())
break; // reached end of pData
else {
// The condition in which pData values will be
// translated into pixel values
// find the starting iterator
if (cx[ii - 1] < 0)
iStrt = pData.cbegin();
else
iStrt = iCnst cx[ii - 1];
// Find the end iterator
if (cx[ii] >= pData.size())
iStop = pData.cend();
else
iStop = iCnst cx[ii];
/* ----- Rest of the code ----- */
}
}
}
}
Также следует отметить, что до этого я использовал QVector
вместо std::vector
и у меня никогда не было этого предупреждения QVector
.
Комментарии:
1. предупреждение не означает, что ваш код неверен. Это просто означает, что при определенных обстоятельствах это может быть неправильно, и в сообщении объясняется, почему. Если это не применимо в вашем случае, у вас есть два варианта: исправить код, чтобы отключить предупреждение, или проигнорировать предупреждение
2. Если вы не хотите использовать отрицательные индексы (что возможно, но используется очень редко), я рекомендую всегда использовать
unsigned
типы для индексов массива.3. @Someprogrammerdude Если цикл начинается,
0
тогда становится условием остановкиii < cx.size() - 1
, что вызовет следующее предупреждение 😉4. Кто, какое ужасно написанное сообщение об ошибке. «приведение результата» неверно — в коде нет приведений. И 4-байтовый против 8-байтового не проблема. Проблема заключается в преобразовании значения со знаком в значение без знака — преобразование отрицательного значения может привести к неожиданностям.
5. @idclev463035818 Не могли бы вы поделиться тем, как лучше всего это сделать в этом случае? У меня самого иногда возникают подобные проблемы при использовании размеров векторов, поэтому меня лично интересовал бы «лучший» или стандартный способ настройки цикла в таком случае, чтобы он был относительно безопасен от ошибок, а компилятор был доволен даже при строгих настройках.
Ответ №1:
Я решил это с помощью const_iterator
, std::prev
и std::next
std::vector<int> cx;
// code to fill cx
// Iterators for cx
std::vector<int>::const_iterator ix0;
std::vector<int>::const_iterator ix1;
ix1 = cx.cbegin();
for(ix0 = cx.cbegin(); ix0 != std::prev(cx.cend()); ix0){
ix1 = std::next(ix1);
if (*ix1 < 0)
continue;
else if (*ix0 >= pData.size())
break;
else {
if (*ix0 < 0)
iStrt = pData.cbegin();
else
iStrt = std::next(pData.cbegin(), *ix0);
if (*ix1 >= pData.size())
iStop = pData.cend();
else
iStop = std::next(pData.cbegin(), *ix1);
}
}
Я еще не пробовал всю функцию целиком. Я обновлю, если это не сработает.