2015-11-26 10 views
1

Я продолжаю получать эту ошибку «Недействительная операция с плавающей точкой».Неверная операция с плавающей запятой

Я на Delphi 7.

uses 
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
TlHelp32, Dialogs, StdCtrls, ExtCtrls, Buttons, ComCtrls; 

var //global 
PHandle, cancel, bytes, scantype: integer; 

...

procedure Tmain.scanbtnClick(Sender: TObject); 
    var max, address: Integer; 
    floatinput, floatinput1, floatinput2, datafloat: Real; 
    x: cardinal; 
    itm: TListItem; 
begin 

    floatinput := StrToFloat(Trim(valueinput.Text)); 
    floatinput1 := StrToFloat(Trim(valueinput1.Text)); 
    floatinput2 := StrToFloat(Trim(valueinput2.Text)); 

    if floatinput2 < floatinput1 then 
    begin 
    floatinput1 := floatinput1 + floatinput2; 
    floatinput2 := floatinput1 - floatinput2; 
    floatinput1 := floatinput1 - floatinput2; 
    end; 

    result.Show; 

    x := 0; 
    address := 0; 

    result.resultlist.Clear; 

    repeat 
    Application.ProcessMessages; 
    statusbar1.Panels.Items[1].Text := 'Searching... ' + IntToStr(address * 100 div max) + '% (' + IntToStr(address div bytes) + ' out of ' + IntToStr(max div bytes) + ').'; 

    if ReadprocessMemory(PHandle, Ptr(address), @datafloat, bytes, x) then 
     begin 
     if (x > 0) then 
     begin 
      if scantype = 0 then 
      begin 
      if datafloat = floatinput then    //error here 
      begin 
       itm := result.resultlist.Items.Add; 
       itm.Caption := '0x' + IntToHex(address,8); 
       itm.SubItems.Add(FormatFloat('0.0#########', datafloat)); 
      end; 
      end; 
      if scantype = 1 then 
      begin 
      if datafloat > floatinput    //also here 
      then begin 
       itm := result.resultlist.Items.Add; 
       itm.Caption := '0x' + IntToHex(address,8); 
       itm.SubItems.Add(FormatFloat('0.0#########', datafloat)); 
      end; 
      end; 
      if scantype = 2 then 
      begin 
      if datafloat < floatinput  //here too 
      then begin 
       itm := result.resultlist.Items.Add; 
       itm.Caption := '0x' + IntToHex(address,8); 
       itm.SubItems.Add(FormatFloat('0.0#########', datafloat)); 
      end; 
      end; 
      if scantype = 2 then 
      begin 
      if (dataint <= intinput2) and (dataint >= intinput1) //even here 
      then begin 
       itm := result.resultlist.Items.Add; 
       itm.Caption := '0x' + IntToHex(address,8); 
       itm.SubItems.Add(FormatFloat('0.0#########', datafloat)); 
      end; 
      end; 

     end; 
     end; 

    if x <> 0 
    then address := address + x 
    else address := address + bytes; 

    until (address >= Max) or (cancel = 1); 

end; 

Я даже проверил на окно центрального процессора, и это происходит потому, что его пытается загрузить значение с плавающей запятой из указатель, указывающий на нулевое значение.

Это не ReadMemory, потому что этот маленький фрагмент кода находится в цикле while и возвращает его перед запуском этой ошибки.

Что мне делать?

Заранее спасибо.

+0

Каким типом данных является datafloat? Вы сравниваете его с вариантом (Null), но вариант не является типом, который был бы совместим с ReadProcessMemory. Вы хотите использовать Double? –

+0

Код, который вы опубликовали, не будет компилироваться, так как единственное допустимое использование 'NULL' в Delphi - это использование вариантов. Пожалуйста, напишите полный ** код ** **, который вы используете. Просить нас отлаживать код, который на самом деле не является вашим кодом, является пустой тратой вашего времени и нашего. Опубликуйте компилируемый MCVE, который демонстрирует проблему, если вы хотите получить помощь здесь. –

+0

@GerryColl данныеfloat реальный. Не могли бы вы объяснить мне, что именно происходит, когда я пытаюсь сравнить значение с нулем? – D3X

ответ

4

Есть две потенциальные проблемы с кодом, который мы можем видеть.

Прежде всего, вы не проверяете возвращаемое значение ReadProcessMemory. Этот вызов может потерпеть неудачу по разным причинам. Поскольку вы не проверяете наличие ошибок, у вас нет способа узнать, удалось ли выполнить вызов функции. Всегда проверяйте API-запросы на успех. Прочтите документы в MSDN, чтобы узнать, как это сделать. Обычно это включает проверку возвращаемого значения функции, как это имеет место здесь. Если функция не работает, переменная с плавающей запятой может содержать неинициализированные данные и может возникнуть ошибка.

Другая проблема заключается в том, что datafloat заполняется путем считывания байтов из другого процесса. Если эти байты не представляют действительное значение с плавающей запятой, тогда исключение будет поднято, если вы попытаетесь использовать это значение. Не все битовые шаблоны представляют собой допустимые значения с плавающей запятой. Например, вы, возможно, натолкнулись на сигнальное значение NaN. Возможно, вам следует сравнить с CompareMem, учитывая, что вы, кажется, читаете произвольную память в том, что выглядит как попытка перепроектировать какую-либо другую программу. Тестирование побитовым сравнением позволит избежать риска загрузки недопустимых значений в плавающие регистры.

И, наконец, я не уверен, что вы имеете в виду, проверив значение с плавающей запятой против null, независимо от того, null есть. Значения с плавающей запятой не являются нулевыми. Очень вероятно, что у вас есть значительное недоразумение.

+0

Итак, я изменил свой код, и теперь я только продолжаю, если результат ReadProcessMemory является истинным, а затем я проверяю, является ли количество прочитанных байтов> 0, и даже если я не совсем понимаю, почему работала процедура comparemem , но что, если я хочу знать, если datafloat> floatinput? Разве я не могу сравнить два реальных значения? – D3X

+0

Фактически .. nope. CompareMem возвращает false даже тогда, когда он должен возвращать true, когда я использую нормальное сравнение, он возвращает только значения, которые он должен, но всегда наступает в этой ошибке через некоторое время. – D3X

+0

Хорошо, я исправил его, ваш ответ действительно был действительно полезен. То, что я сделал, было объявлено «Math» в использовании, а затем проверить, является ли «datafloat» не NaN, используя процедуру IsNan, спасибо. – D3X