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

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

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

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 02.11.2009, 19:09   #1
KingOfNothing
Пользователь
 
Регистрация: 06.02.2009
Сообщений: 89
По умолчанию Delphi - непонятный access violation

В процедуре ReadElementFromTxt происходит access violation:

Код:
function ReadElementFromTxt(var f: textfile): TDisc;
var
  r:TDisc;
  str:string;
begin
      readln(f, r.KodDysc);
      readln(f, r.NazvDysc);
      readln(f, r.KodCycl);
      readln(f, str); // в этой строке - перед этим читает нормально
      r.ObsDysCred := StrToFloat(str);
      readln(f, str);
      if str='ИСТИНА' then
          r.LabRob:=true
      else
          r.LabRob:=false;
      ReadElementFromTxt := r;
end;
Структура:
Код:
TDisc = record
    KodDysc: string[5];
    NazvDysc: string[80];
    KodCycl: integer;
    ObsDysCred: real;
    LabRob: boolean;
  end;
Файл:
Код:
40
Name 1
1
2.0
ИСТИНА
Помогите плиз в чем может быть беда? пробовал перенести процедуру в другой проект и читать с того же файла - вроде всё ок.
Если вдруг захотите сказать мне спасибо - воспользуйтесь кнопкой "Добавить отзыв"
KingOfNothing вне форума Ответить с цитированием
Старый 02.11.2009, 19:15   #2
mihali4
*
Старожил
 
Регистрация: 22.11.2006
Сообщений: 9,201
По умолчанию

access violation, как правило, означает обращение к несуществующей переменной и проч.
Проверьте внимательно.
Пройдите по шагам и посмотрите на какой строке "затык".
mihali4 вне форума Ответить с цитированием
Старый 02.11.2009, 19:19   #3
KingOfNothing
Пользователь
 
Регистрация: 06.02.2009
Сообщений: 89
По умолчанию

Цитата:
Сообщение от mihali4 Посмотреть сообщение
access violation, как правило, означает обращение к несуществующей переменной и проч.
Проверьте внимательно.
Пройдите по шагам и посмотрите на какой строке "затык".
я показал в коде в какой строке - до неё нормально, а потом при попытке выполнить чтение в строку - вылетает.
Если вдруг захотите сказать мне спасибо - воспользуйтесь кнопкой "Добавить отзыв"
KingOfNothing вне форума Ответить с цитированием
Старый 02.11.2009, 20:38   #4
KingOfNothing
Пользователь
 
Регистрация: 06.02.2009
Сообщений: 89
По умолчанию

бред, создал новый проект скопировал туда всеь код и всё заработало
UPD
всё еще интересней - как только добавляю ТМемо на форму, опять сразу выпадает Access violation
Если вдруг захотите сказать мне спасибо - воспользуйтесь кнопкой "Добавить отзыв"

Последний раз редактировалось KingOfNothing; 02.11.2009 в 20:41.
KingOfNothing вне форума Ответить с цитированием
Старый 02.11.2009, 21:18   #5
KingOfNothing
Пользователь
 
Регистрация: 06.02.2009
Сообщений: 89
По умолчанию

Выложу весь код. Народ, помогите - очень нужно закончить работу. Хоть проверьте, вдруг это только на моей машине такое.
Код:
unit Unit1;

interface

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

const
    segNum = 7;
    elemNum = 2;
    
type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TDisc = record
    KodDysc: string[5];
    NazvDysc: string[80];
    KodCycl: integer;
    ObsDysCred: real;
    LabRob: boolean;
  end;

  TFile = file of TDisc;

  THashTable = array of integer;

var
   Form1: TForm1;

implementation

{$R *.dfm}

function hash(key:integer):integer;
begin
  hash := key mod segNum;
end;

procedure createHashTable(var table:THashTable);
var
  i:integer;
begin
  setlength(table, segNum);
  for i:=0 to segNum do
    table[i]:=0;
end;

function ReadElementFromTxt(var f: textfile): TDisc;
var
  r:TDisc;
  str:string;
begin
      readln(f, r.KodDysc);
      readln(f, r.NazvDysc);
      readln(f, r.KodCycl);
      readln(f, str);
      r.ObsDysCred := StrToFloat(str);
      readln(f, str);
      if str='ÈÑÒÈÍÀ' then
          r.LabRob:=true
      else
          r.LabRob:=false;
      ReadElementFromTxt := r;
end;

function getOffset(hashValue:integer; lastElem:integer):integer;
begin
  getOffset := hashValue * elemNum + lastElem;
end;

procedure writeByOffset(var f:TFile; offset:integer; rec:TDisc);
begin
  Seek(f, offset);
  Write(f, rec);
end;

function AddElement(var mainF:TFile; var overflowF:TFile; rec:TDisc; var HashTable:THashTable):boolean;
var
  hashValue,
  offset:integer;
begin
      hashValue := hash(rec.KodCycl);
      if (hashTable[hashValue] = elemNum) then
          begin
            write(overFlowF, rec);
            AddElement := true;
          end
        else
          begin
              offset := getOffset(hashValue, hashTable[hashValue]);
              writeByOffset(mainF, offset, rec);
              AddElement := false;
          end;
end;

function createBinFile(main:string; overFlow:string; txt: string; var HashTable:THashTable):integer;
var
  mainF:TFile;
  overflowF:TFile;
  txtF: textfile;
  rec: TDisc;
  offset,
  overflowNum:integer;
  str:string;
begin
  overflowNum := 0;
  
  AssignFile(mainF, main);
  AssignFile(overFlowF, overflow);
  AssignFile(txtF, txt);

  Rewrite(mainF);
  Rewrite(overflowF);
  Reset(txtF);

  while not Eof (txtF) do
    begin;
      rec := ReadElementFromTxt(txtF);
      if (AddElement(mainF, overflowF, rec, hashTable)) then
        inc(overflowNum);
    end;

  CloseFile(mainF);
  CloseFile(overFlowF);
  CloseFile(txtF);
  createBinFile := overflowNum;
end;

function getFileAsString(filename:string):string;
var
  f: TFile;
  s:string;
  i:integer;
  m:Tdisc;
begin
  AssignFile(f, filename);
  Reset(f);
  s:= #13#10 +'KodDysc' + #9
  + 'KodCycl' + #9
  + 'ObsDysCred' + #9
  + 'LabRob' + #9
  + 'NazvDysc' + #13#10;
  for i:=0 to filesize(f)-1 do
  begin
    read(f, m);
    s:= s + m.KodDysc + #9
    + IntToStr(m.KodCycl) + #9
    + FloatToStrF(m.ObsDysCred, ffFixed, 1, 1) + #9#9
    + BoolToStr(m.LabRob, true) + #9
    + m.NazvDysc + #13#10;
  end;
  getFileAsString := s;
  CloseFile(f);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
    hashTable:THashTable;
    N: integer;
    f: TextFile;
    rec : TDisc;
begin
  createHashTable(hashTable);
  N := createBinFile('test1.dat', 'test1.dat.overflow', 'test1.txt', hashTable);
end;

end.
Если вдруг захотите сказать мне спасибо - воспользуйтесь кнопкой "Добавить отзыв"
KingOfNothing вне форума Ответить с цитированием
Старый 02.11.2009, 23:22   #6
Скандербег
Форумчанин
 
Регистрация: 04.04.2009
Сообщений: 438
По умолчанию

Код:
  setlength(table, segNum);
  for i:=0 to segNum do
    table[i]:=0;
Здесь логическая ошибка.
Количество элементов размещаемых в памяти - segNum, а присвоение в цикле происходит количеству элементов больше на единицу. Т.е. присвоение значения несуществующему элементу (table[segNum]).
Естественным образом должно быть так:
Код:
  setlength(table, segNum);
  for i:=0 to segNum-1 do
    table[i]:=0;
На будущее: если хотите чтобы вам помогали охотно, не заставляйте помощников догадываться что у вас находится на форме - предоставляйте и файл .DFM. Ведь, вполне возможно, что компоненты на форме могут иметь иные значения свойств, чем устанавливаемые по умолчанию.
Второе, если у вас в коде происходит считывание из заранее подготовленного файла (Reset(txtF);), то дайте хотя бы общую информацию что там может находится (ошибка же происходит при попытке открыть несуществующий файл).

--- добавлено ---
Да, и при работе программы (при условии, что файл test1.txt существует) никаких ошибок не происходит.

Последний раз редактировалось Скандербег; 02.11.2009 в 23:36.
Скандербег вне форума Ответить с цитированием
Старый 02.11.2009, 23:59   #7
KingOfNothing
Пользователь
 
Регистрация: 06.02.2009
Сообщений: 89
Хорошо

Цитата:
Да, и при работе программы (при условии, что файл test1.txt существует) никаких ошибок не происходит.
Ошибка происходит, когда
Код:
setlength(table, segNum);
  for i:=0 to segNum do
    table[i]:=0;
Глупая очень ошибка, я даже запомнил как её сделал, только не запомнил почему :-). Перезатирается себе спокойненько какая-то область памяти и access violation не вылазит в месте непосредственной ошибки. Поэтому так долго и искал её. Спасибо еще раз.

P.S. test1.txt всегда существовал и его структура приведена в первом посте.
Если вдруг захотите сказать мне спасибо - воспользуйтесь кнопкой "Добавить отзыв"
KingOfNothing вне форума Ответить с цитированием
Старый 03.11.2009, 00:46   #8
Скандербег
Форумчанин
 
Регистрация: 04.04.2009
Сообщений: 438
По умолчанию

Цитата:
Сообщение от KingOfNothing Посмотреть сообщение
Перезатирается себе спокойненько какая-то область памяти и access violation не вылазит в месте непосредственной ошибки. Поэтому так долго и искал её.
Отлавливается такая ошибка в раз:
в установках компилятора отключается флаг "Optimization" и включается флаг "Range cheсking". Тогда в отладке ошибка "вылазит" именно там, где и случается.

Цитата:
Сообщение от KingOfNothing Посмотреть сообщение
P.S. test1.txt всегда существовал и его структура приведена в первом посте.
Всегда существовала вселенная, а файла с таким именем и такой структурой на моей машинке никогда не было. Догадаться, что структура, приведенная в первом посте относится к этому файлу было слегка затруднительно. Есть же и другие файлы, с которыми программа работает. Без обиды, но, это, видно, крест всех помогающих - напрягать телепатию.

Может пригодится:
Код:
//  if str='ИСТИНА' then
//    r.LabRob:=true
//  else
//    r.LabRob:=false; //заменяется на более компактную конструкцию:
  r.LabRob := str = 'ИСТИНА';

//  ReadElementFromTxt := r; 
//турбопаскалевский синтаксис там где он не нужен, лучше начинать забывать
//Borland все же рекомендует возвращать результат функции через служебную переменную:
  Result := r;
Скандербег вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
access violation at address UnChanter Общие вопросы Delphi 22 07.02.2011 11:00
ListView и Access violation Ronder Помощь студентам 6 22.08.2009 11:19
Ошибка Access Violation AHTuKiLLeR Общие вопросы Delphi 8 02.06.2009 10:48
Access Violation SunKnight Общие вопросы Delphi 2 05.06.2008 16:46
Access Violation Carbon Общие вопросы Delphi 12 18.09.2007 19:55