Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.05.2009, 22:36   #1
g0liath
Пользователь
 
Регистрация: 16.02.2008
Сообщений: 10
По умолчанию Delphi... Проблема с динамическими массивами (попытка чтения по неправильному адресу)

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

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

Ошибка: систематически (твердой закономерности не найдено) выскакивает ошибка, которая сообщает о попытке чтения по неправильному адресу.

Код:
  TAChar = array [1..6] of Char;
//Запись
  TRecord = record
    Key: TAChar;
    Number: Word;
  end;
//Пакет
  TPPacket = ^TPacket;
  TPacket = record
    ARecords: array of TRecord;
    Over: TPPacket;
  end;

var
  Form1: TForm1;
  ARecords1: array [1..1000] of TRecord;
  ARecords2: array [1..200] of TRecord;
  APackets: array of TPacket;
  
implementation

{$R *.dfm}

//Сгенерировать массивы ключей
procedure TForm1.Button1Click(Sender: TObject);
const
  CharTable: string = 'ABCDEFGHIJKLMNOPQSTUVWXYZ';
var
  I, J: Word;
  B: Boolean;
begin
  Randomize;
  for I := 1 to 1000 do begin
    repeat
      B := True;
      for J := 1 to 6 do
        ARecords1[I].Key[J] := CharTable[Random(Length(CharTable))+1];
      for J := I-1 downto 1 do
        if ARecords1[I].Key = ARecords1[J].Key then B := False;
    until B;
    ARecords1[I].Number := I;
    Form1.StringGrid1.Cells[0,I-1] := ARecords1[I].Key;
    Form1.StringGrid1.Cells[1,I-1] := IntToStr(ARecords1[I].Number);
  end;
  for I := 1 to 200 do begin
    repeat
      B := True;
      for J := 1 to 6 do
        ARecords2[I].Key[J] := CharTable[Random(Length(CharTable))];
      for J := I-1 downto 1 do
        if ARecords2[I].Key = ARecords2[J].Key then B := False;
      for J := 1 to 1000 do
        if ARecords2[I].Key = ARecords1[J].Key then B := False;
    until B;
    ARecords2[I].Number := I;
    Form1.StringGrid2.Cells[0,I-1] := ARecords2[I].Key;
    Form1.StringGrid2.Cells[1,I-1] := IntToStr(ARecords2[I].Number);
  end;
end;

[часть кода вырезана]

//Хеширование
procedure TForm1.Button2Click(Sender: TObject);
var
  I, J, N, B, R: Word;
  Flag: Boolean;
  P: TPPacket;
begin
  B := StrToInt(Form1.ComboBox1.Text);
  R := Round(1200/B);
  SetLength(APackets, B);
  for I := 0 to B-1 do begin
    SetLength(APackets[I].ARecords, Round(1200/B));
    for J := 0 to Round(1200/B)-1 do
      APackets[I].ARecords[J].Number := 0;
  end;

  for I := 1 to 1000 do begin
    case Form1.ComboBox2.ItemIndex of
      0: N := AverageSquares(ARecords1[I].Key, B);
      1: N := FoldingMethod(ARecords1[I].Key, B);
    end;

    Flag := False;
    P := @APackets[N];
    while P.Over <> Nil do
      P := P.Over;
    while Flag = False do begin
      for J := 0 to Round(1200/B)-1 do
        if P.ARecords[J].Number = 0 then begin
          P.ARecords[J] := ARecords1[I];
          Flag := True;
          Break;
        end;
      if Flag = False then begin
        GetMem(P.Over, SizeOf(TPacket));
        P := P.Over;
        P.Over := Nil;
        SetLength(P.ARecords, Round(1200/B));
        for J := 0 to Round(1200/B)-1 do
          P.ARecords[J].Number := 0;
        P.ARecords[0] := ARecords1[I];
        Flag := True;
      end;
    end;
  end;
end;
Когда появляется ошибка: сперва генерируется массив, потом в хэш-таблицу загоняется 1000 элементов. Вот именно в этот момент и происходит ошибка. Не всегда. Вероятность появление ошибки повышается при изменении числа пакетов в ComboBox1.
Вложения
Тип файла: zip Project.zip (7.5 Кб, 9 просмотров)
g0liath вне форума Ответить с цитированием
Старый 06.05.2009, 03:21   #2
Скандербег
Форумчанин
 
Регистрация: 04.04.2009
Сообщений: 438
По умолчанию

"Попытка скрестить бульдога с носорогом всегда приводит к непредсказуемым результатам" .
Исправления с комментариями в прицепе.
Вложения
Тип файла: zip project_update.zip (13.6 Кб, 11 просмотров)

Последний раз редактировалось Скандербег; 06.05.2009 в 07:56. Причина: Оптимизация измененного кода
Скандербег вне форума Ответить с цитированием
Старый 12.05.2009, 08:45   #3
g0liath
Пользователь
 
Регистрация: 16.02.2008
Сообщений: 10
По умолчанию

Огромное спасибо. Я смог сам решить проблему и сдать работу, но комментарии были крайне интересны и познавательны.
g0liath вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Задача с динамическими массивами _grusha_ Помощь студентам 2 22.04.2009 19:46
Проблема с МАССИВАМИ! Help! GorNikSar Паскаль, Turbo Pascal, PascalABC.NET 3 19.12.2008 13:43
Проблема с динамическими массивами Arassir Помощь студентам 2 11.11.2008 00:15
Помогите решить задачу с динамическими массивами и строками символов Andres Помощь студентам 2 31.01.2008 11:09