C26451 c как исправить

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).
Строки: 9 14 15 16 17 18 19;
Выражение: j+1

Собственно почему? Я же прибавляю 4байтовый int (1) к 4байтовому j.
Я в курсе, что возвращаемое значение метода .size() не int, а size_t, но ни замена int на size_t в for, ни приведение к int не решают эту проблему. Как можно решать это?

Функция

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
template <typename T>
int SortVector(vector<Box<T>>& alph)//Сортировка по возрастанию
{
    WhiteBox<T> temp;
    for (int i = 0; i < alph.size() - 1; i++)
    {
        for (int j = 0; j < alph.size() - i - 1; j++)
        {
            if (alph[j].Get_maxLimit() > alph[j + 1].Get_maxLimit()) 
            {
                temp.Set_maxLimit(alph[j].Get_maxLimit());
                temp.Set_minLimit(alph[j].Get_minLimit());
                temp.Set_symbol(alph[j].Get_symbol());
                alph[j].Set_maxLimit(alph[j + 1].Get_maxLimit());
                alph[j].Set_minLimit(alph[j + 1].Get_minLimit());
                alph[j].Set_symbol(alph[j + 1].Get_symbol());
                alph[j + 1].Set_maxLimit(temp.Get_maxLimit());
                alph[j + 1].Set_minLimit(temp.Get_minLimit());
                alph[j + 1].Set_symbol(temp.Get_symbol());
            }
        }
    }
    return 0;
}

Класс

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template <typename T>
class Box
{
protected:
    T minLimit = numeric_limits<T>::min();                              //Нижняя граница отрезка
    T maxLimit = numeric_limits<T>::min();                              //Верхняя граница отрезка
 
public:
    Box() {};
    Box(T min, T max)
    {
        minLimit = min;
        maxLimit = max;
    };
 
    //Set-functions
    void Set_minLimit(T value) { minLimit = value; }
    void Set_maxLimit(T value) { maxLimit = value; }
 
    //Get-functions
    T Get_minLimit() { return minLimit; };
    T Get_maxLimit() { return maxLimit; };
};

Main

C++
1
2
3
4
5
6
7
8
//Зависимости опущены
int main()
{
vector<Box<uint32_t>> alphabet;
//Тут мог быть ввод с клавиатуры
SortVector(alphabet);
return 0;
}



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

27.01.2020, 18:33

Ответы с готовыми решениями:

Переполнение
При вводе слишком большого числа (например: 4444444444444444) программа зацикливается и постоянно…

Переполнение
Доброго времени суток! Есть код:

void menu()
{
IndexList Universal;
List *tmp = NULL;
int…

Переполнение
При выводе числа происходит переполнение и пребовление числа 64. Подскажите почему прибавилось…

Exception переполнение
Подскажите пожалуйста, вот есть для встроенная библиотека для обработки ошибко exception.
В ней…

4

6576 / 4561 / 1843

Регистрация: 07.05.2019

Сообщений: 13,726

27.01.2020, 19:08

2

Цитата
Сообщение от Battary
Посмотреть сообщение

Я в курсе, что возвращаемое значение метода .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

Цитата
Сообщение от oleg-m1973
Посмотреть сообщение

Используй size_t в обоих циклах, для i и для j. Зачем тебе там int?

Я пробовал, ошибка не уходит. А int там нужен, потому что массив не больше 1000.



0



6576 / 4561 / 1843

Регистрация: 07.05.2019

Сообщений: 13,726

27.01.2020, 21:10

4

Лучший ответ Сообщение было отмечено Battary как решение

Решение

Цитата
Сообщение от Battary
Посмотреть сообщение

Я пробовал, ошибка не уходит. А int там нужен, потому что массив не больше 1000.

Во-первых, это не ошибка, а предупреждение, в принципе можно забить.
Во-вторых, int там не нужен, это не от размера зависит.
В-третьих, попробуй привести единицу к size_t: i < alph.size() — size_t(1);



0



большой ДЕН

1 / 1 / 0

Регистрация: 01.05.2017

Сообщений: 144

26.09.2020, 19:15

5

Привет.
Есть такая функция

C++
1
2
3
4
5
template<typename T>
    inline double lef1(T b, int k) {
 
        return (0.75 + 0.25 * pow(static_cast<double> (b) / (k - 1), 2 * k - 3)) / 0.5;
    }

Выражение «(k — 1)» подчеркнутос предупреждением «c26451 арифметическое переполнение использование оператора «-» на байтовом значении 4 и приведение результата к байтовому значению 8″
Я совсем не понимаю почему так. Подскажите, пожалуйста, как правильно должно быть



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

26.09.2020, 19:15

Помогаю со студенческими работами здесь

Задача на переполнение
Вот такая задачка: Дано число в двоичном виде состоящее из 1млн (короче из огромного количества)…

Переполнение стека
Хочу полюбопытствовать. Вычитал недавно, что на стек выделяется ограниченная область памяти, и в…

Переполнение double
Здравствуйте!

как отловить переполнение при расчетах double;

double db =…

Переполнение буфера
Добрый день! В общем:
#include &quot;stdafx.h&quot;
#include &lt;iostream&gt;
using namespace std;

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);
    }
}
  

Я еще не пробовал всю функцию целиком. Я обновлю, если это не сработает.

Понравилась статья? Поделить с друзьями:
  • Как составит расписание учебных занятий в вузе
  • Как найти человека по продвижению товара
  • Как на карте найти малайзию
  • Security как найти телефон
  • Как правильно составить документ заявление