powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как найти ошибку?
25 сообщений из 30, страница 1 из 2
Как найти ошибку?
    #39704874
Валерий666
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вобщем не могу понять что и откуда берется. После окончания события вылазит "Invalid pointer operation" или вовсе крэш памяти.
Все отрабатывает, отладчик все проглатывает, потреково все отлично, нигде не вылазят исключения, нет пустых данных, предпросмотр отчета отображается. После закрытия окна предпросмотра - ошибка. Думал дело в файле отчета, проверил, даже файл подменил другим. Ситуация не поменялась.
Вот код обработчика:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
procedure TForm8.sBitBtn1Click(Sender: TObject);
var m: TfrxRichView;
theme_array: array of integer;
tmp_array: array of string;
i:integer;
all: array of integer;
begin
 // Получаем список номенклатуры из справочника
  GetInfoRepSQL('SELECT * FROM kodvopr WHERE (torep=1) ORDER BY KOD11');
  //Определяем размер массивов
  SetLength(tmp_array, Form1.ZReport.RecordCount);
  SetLength(theme_array, Form1.ZReport.RecordCount);
  SetLength(all, 5);
  Form1.ZReport.First;
    while not Form1.ZReport.Eof do
      begin     // записываем в массив циферные обозначения номенклатуры
        tmp_array[Form1.ZReport.RecNo-1]:=Form1.ZReport.FieldByName('KODnom').AsString;
        Form1.ZReport.Next;
      end;

// По циклу из массива номенклатуры, делаем запросы по базе обращений
  for i:=0 to length(tmp_array)-1 do
    begin
        GetInfoRepSQL('SELECT themeid FROM register WHERE themeid=('''+tmp_array[i]+''')');
        theme_array[i]:=Form1.ZReport.RecordCount;
        all[0]:=all[0]+Form1.ZReport.RecordCount; // общее количество
    end;
  all[1]:=theme_array[0]+theme_array[1]+theme_array[2]+theme_array[3]+theme_array[4]+theme_array[5]+theme_array[6]+theme_array[7]+theme_array[8]+theme_array[9]+theme_array[10];
  all[2]:=theme_array[7]+theme_array[8];
  all[3]:=theme_array[11]+theme_array[12]+theme_array[13];
  all[4]:=theme_array[17]+theme_array[18]+theme_array[19];
  all[5]:=theme_array[20]+theme_array[21]+theme_array[22]+theme_array[23]+theme_array[24]+theme_array[25]+theme_array[26]+theme_array[27];

  Form1.frxReport1.LoadFromFile(Form1.sPath + '\reports\' + 'theme.fr3', true);

// Заполняем данными отчет
with Form1.frxReport1.Variables do
     begin
        Variables[' ' + 'MyDefaultCategory'] := Null;  //Создаем пустую категорию для дальнейшего создания переменных в отчете
        Variables['period'] := quotedstr(sDateEdit1.Text+' - '+sDateEdit2.Text);

            for i:=1 to length(theme_array) do
            begin     // заполняем переменные отчета
                     Variables['t'+inttostr(i)] := quotedstr(inttostr(theme_array[i]));
            end;

            for i:=0 to 5 do
            begin     // заполняем результирующие переменные отчета
              Variables['all'+inttostr(i)] := quotedstr(inttostr(all[i]));
            end;

      end;
  frxReport1.ShowReport(true);
end;


Куда копать?
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704878
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Валерий666,

all[5]
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704879
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Валерий666SetLength(tmp_array, Form1.ZReport.RecordCount);

У меня для тебя плохие новости: RecordCount не всегда возвращает реальное количество
записей в Dataset-е.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704882
goldmi45
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Валерий666
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
procedure TForm8.sBitBtn1Click(Sender: TObject);
var m: TfrxRichView;
theme_array: array of integer;
tmp_array: array of string;
i:integer;
all: array of integer;
begin
 // Получаем список номенклатуры из справочника
  GetInfoRepSQL('SELECT * FROM kodvopr WHERE (torep=1) ORDER BY KOD11');
  //Определяем размер массивов
  SetLength(tmp_array, Form1.ZReport.RecordCount);
  SetLength(theme_array, Form1.ZReport.RecordCount);
  SetLength(all, 5); // от 0 до 4
  Form1.ZReport.First;
    while not Form1.ZReport.Eof do
      begin     // записываем в массив циферные обозначения номенклатуры
        tmp_array[Form1.ZReport.RecNo-1]:=Form1.ZReport.FieldByName('KODnom').AsString;
        Form1.ZReport.Next;
      end;

// По циклу из массива номенклатуры, делаем запросы по базе обращений
  for i:=0 to length(tmp_array)-1 do
    begin
        GetInfoRepSQL('SELECT themeid FROM register WHERE themeid=('''+tmp_array[i]+''')');
        theme_array[i]:=Form1.ZReport.RecordCount;
        all[0]:=all[0]+Form1.ZReport.RecordCount; // общее количество
    end;
  all[1]:=theme_array[0]+theme_array[1]+theme_array[2]+theme_array[3]+theme_array[4]+theme_array[5]+theme_array[6]+theme_array[7]+theme_array[8]+theme_array[9]+theme_array[10];
  all[2]:=theme_array[7]+theme_array[8];
  all[3]:=theme_array[11]+theme_array[12]+theme_array[13];
  all[4]:=theme_array[17]+theme_array[18]+theme_array[19];
  all[5]:=theme_array[20]+theme_array[21]+theme_array[22]+theme_array[23]+theme_array[24]+theme_array[25]+theme_array[26]+theme_array[27]; //а это куда?

  Form1.frxReport1.LoadFromFile(Form1.sPath + '\reports\' + 'theme.fr3', true);

// Заполняем данными отчет
with Form1.frxReport1.Variables do
     begin
        Variables[' ' + 'MyDefaultCategory'] := Null;  //Создаем пустую категорию для дальнейшего создания переменных в отчете
        Variables['period'] := quotedstr(sDateEdit1.Text+' - '+sDateEdit2.Text);

            for i:=1 to length(theme_array) do
            begin     // заполняем переменные отчета
                     Variables['t'+inttostr(i)] := quotedstr(inttostr(theme_array[i]));
            end;

            for i:=0 to 5 do // 0,1,2,3,4,5 - итого 6
            begin     // заполняем результирующие переменные отчета
              Variables['all'+inttostr(i)] := quotedstr(inttostr(all[i]));
            end;

      end;
  frxReport1.ShowReport(true);
end;


Куда копать?
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704901
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хоть и есть ошибка в непонимание выделенного массива, то что элементы с нуля.


Но, ошибка - "Invalid pointer operation" означает обращение к не выделенной памяти указателя.

А неверное обращение к элементу должно расцениваться как Range check error
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704904
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Информация о такой ошибки могла бы стать строка
Код: pascal
1.
        tmp_array[Form1.ZReport.RecNo-1]:=Form1.ZReport.FieldByName('KODnom').AsString;



В диалоговом окне, трудно нажать break ?
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704908
Любезный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Живой пример, как не надо писать приложения. Элементы одной формы обращаются к элементам другой... Вынеси логику в отдельный от интерфейса пользователя модуль и делай все в нем. Потом ведь допиливать и поддерживать проще будет.
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704909
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторfor i:=0 to length(tmp_array)-1 do

лучше использовать Low и High
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704910
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
X11авторfor i:=0 to length(tmp_array)-1 do

лучше использовать Low и High
Чем лучше ?
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704926
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecator,

при использовании Low и High границы массива нужно менять только в одном месте, ибо не все массивы начинаются с 0 ))))

простейший пример:

Array1: array[0..999] of Byte;

for I := 0 to 999 do // при изменении описания массива здесь тоже нужно менять
Array1[I] := 1;

for I := Low(Array1) to High(Array1) do // при изменении описания массива здесь ничего менять не нужно
Array1[I] := 1;

а еще вспоминаем кроссплатформенность)) Хотя кому я говорю, ты даже до древнейшей D7 не заапгрейдился)
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704930
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecatorX11пропущено...


лучше использовать Low и High
Чем лучше ?

чем от 0 до -1
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704935
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А если массив начинается не 0 или даже не 1?

Var
X: array[3..10] of Integer;
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704938
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
var
 I: Byte;
 X: array[3..10] of Integer;
 Sum: Integer;
begin
 for I:= Low(X) to High(X) do X[I]:=I;
 Sum:= 0;
 for I:= Low(X) to High(X) do Sum:= Sum+ X[I];
end;



Если в объявлении массива поменять [3..10] на [5..18], например, то в объявлении цикла ничего менять не придётся
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704947
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ГирлионайльдоНо, ошибка - "Invalid pointer operation" означает обращение к не выделенной памяти указателя.Нет. Она означает повреждение служебной памяти. Например префикса массива
ГирлионайльдоА неверное обращение к элементу должно расцениваться как Range check errorПри включенной проверке Range check
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704957
Валерий666
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkovВалерий666,

all[5]
Спасибо! Глаз замылился...
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704960
Валерий666
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovВалерий666SetLength(tmp_array, Form1.ZReport.RecordCount);

У меня для тебя плохие новости: RecordCount не всегда возвращает реальное количество
записей в Dataset-е.

Это зависит от их количества? Скажем до 10000 я проблем таких не видел
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704964
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Валерий666Это зависит от их количества?

Это зависит от особенностей реализации конкретного класса.

И, кстати, ты уверен, что у тебя все запросы возвращают одинаковое количество записей?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704968
Валерий666
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovВалерий666Это зависит от их количества?

Это зависит от особенностей реализации конкретного класса.

И, кстати, ты уверен, что у тебя все запросы возвращают одинаковое количество записей?..


Имеется ввиду разные или один и то же выполненный 1000 раз?
Пока база не большая 20 записей, все проверяемо и отображается правильно.
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704996
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Валерий666Пока база не большая 20 записей, все проверяемо и отображается правильно.Короче : "Сегодня детских не завезли". Все еще впереди.

Если датасет еще не сфетчил все записи, а транзакция ридкоммиитед, то... дальше сам или еще что-то нужно пояснять?
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39704998
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Валерий666Имеется ввиду разные или один и то же выполненный 1000 раз?

Мне отсюда не видно что делает процедура GetInfoRepSQL(), но я сильно подозреваю, что она
меняет содержимое Form1.ZReport и это содержимое может уже не поместиться в массив,
выделенный под старое количество RecordCount.

Валерий666Пока база не большая 20 записей, все проверяемо и отображается правильно.

20 записей? А что тогда заносится в theme_array с 20-го по 27-й номер?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39705011
Любезный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторА если массив начинается не 0 или даже не 1?
В этом случае Low и High не помогут. Проверял на D2010.
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39705024
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
asutp2defecator,

при использовании Low и High границы массива нужно менять только в одном месте, ибо не все массивы начинаются с 0 ))))

простейший пример:

Array1: array[0..999] of Byte;

for I := 0 to 999 do // при изменении описания массива здесь тоже нужно менять
Array1[I] := 1;

for I := Low(Array1) to High(Array1) do // при изменении описания массива здесь ничего менять не нужно
Array1[I] := 1;

а еще вспоминаем кроссплатформенность))

а ещё можно завести константы, определяющие размерность массива,
и использовать только их (как раз мой вариант)
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39705059
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Нет. Она означает повреждение служебной памяти. Например префикса массива


Доказательства в студию! Если бы так было, то выскочила ошибка AV подобная 'write of address 0xXXXXXXXX'
...
Рейтинг: 0 / 0
Как найти ошибку?
    #39705065
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_При включенной проверке Range check

А вот и нет. Она у меня выскакивает даже при выключенной

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
program Project2;


{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

var
  i, Rand: Integer;
  Arr: array of Integer;

begin
  try
    Randomize;
    while True do
    begin
      Rand := Random(i.MaxValue);
      Writeln(Rand);
      SetLength(Arr, Rand);
      for i := 0 to i.MaxValue - 1 do
        Arr[i] := i;
      Writeln(Arr[i]);
      Readln;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.

...
Рейтинг: 0 / 0
Как найти ошибку?
    #39705179
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ГирлионайльдоА вот и нет. Она у меня выскакивает даже при выключенной
Код: pascal
1.
2.
3.
4.
5.
6.
7.
procedure TForm1.FormCreate(Sender: TObject);
var
  LData: array of Integer;
begin
  SetLength(LData, 1);
  LData[1] := 2;
end;

При подключенном FastMM на выходе из процедуры FastMM ругается на поврежденный футер блока. При отсутствии FastMM на закрытие программы начинаются сыпаться произвольные ошибки.

Если добавить
Код: pascal
1.
{$R+}

то на строке
Код: pascal
1.
LData[1] := 2;

ожидаемый
---------------------------
Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class ERangeError with message 'Range check error'.
---------------------------
Break Continue Help
---------------------------

ГирлионайльдоДоказательства в студию!SysUtils.pas
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
procedure ErrorHandler(ErrorCode: Byte; ErrorAddr: Pointer);
var
  E: Exception;
begin
  case ErrorCode of
    Ord(reOutOfMemory):
      E := OutOfMemory;
    Ord(reInvalidPtr):
      E := InvalidPointer;
    Ord(reDivByZero)..Ord(High(TRuntimeError)):
      E := ExceptTypes[ExceptMap[ErrorCode].EClass].Create(ExceptMap[ErrorCode].EIdent);
  else
    E := CreateInOutError;
  end;
  if ErrorAddr <> nil then
    raise E at ErrorAddr
  else
    raise E;
end;

поискать по исходникам строку reInvalidPtr - задание на дом
ГирлионайльдоЕсли бы так было, то выскочила ошибка AV подобная 'write of address 0xXXXXXXXX'Чушь! Вот именно эта ошибка обозначает обращение к невыделенной (или освобожденной) памяти
...
Рейтинг: 0 / 0
25 сообщений из 30, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как найти ошибку?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]