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

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

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 01.05.2012, 05:40   #1
Anton911
Форумчанин
 
Аватар для Anton911
 
Регистрация: 23.08.2011
Сообщений: 171
Злость Использование record в record

Есть вот такие две записи:
Код:
type pStep=^tStep;
  tStep=record
  StepNumber:integer;
  PlayerName:string;
  WhiteBlack:integer;
  CheckFrom,CheckIn:integer;
  StepPrev,StepNext:pStep;
  end;
  type pArena=^tArena;
  tArena=record
  Player_1,Player_2:string;
  MaxTimeToHod,Resultat,Table,StepCount:integer;
  DateStart,DateFinish:string;
  Steps:pStep;
  ArenaPrev,ArenaNext:pArena;
  end;
В общем создаю проект на делфи, есть несколько арен, у каждой арены есть "шаги"(Steps). Пытаюсь записать новый шаг в определенную арену, но на выделенной строке вылетает access violetion, в чем же ошибка?
Код:
procedure Arena_AddStepToArena(TableId,CheckFrom,CheckIn:integer;PlayerName:string);
var
Arena:pArena;
NewStep:pStep;
begin
Arena:=Arena_GetArenaFromTable(TableId);
new(NewStep);
NewStep.StepNext:=nil;
NewStep.StepPrev:=nil;
NewStep.StepNext:=Arena.Steps;
NewStep.StepNumber:=Arena.StepCount;
NewStep.PlayerName:=PlayerName;
NewStep.CheckIn:=CheckIn;
NewStep.CheckFrom:=CheckFrom;
if Arena.Steps<>nil then Arena.Steps.StepPrev:=NewStep;
Arena.Steps:=NewStep;
inc(Arena.StepCount);
end;
Каждый день узнаю новое...
Anton911 вне форума Ответить с цитированием
Старый 01.05.2012, 10:56   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Код:
if Arena.Steps<>nil then Arena.Steps^.StepPrev:=NewStep;
Steps указатель. Хош добраться к его данным - разименовывай.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 01.05.2012, 16:28   #3
Anton911
Форумчанин
 
Аватар для Anton911
 
Регистрация: 23.08.2011
Сообщений: 171
По умолчанию

Сделал также, но ошибка так и осталась(
Каждый день узнаю новое...
Anton911 вне форума Ответить с цитированием
Старый 01.05.2012, 16:41   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Значит поставь точку прерывания на эту строку, и посмотри чему равны переменные и их поля.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 01.05.2012, 16:48   #5
Anton911
Форумчанин
 
Аватар для Anton911
 
Регистрация: 23.08.2011
Сообщений: 171
По умолчанию

Я так и делал, смотрел чему что равно.
В NewStep.StepNext успешно сохранилась Arena.Steps.
А Arena.Steps.StepPrev и Arena.Steps.StepNext установлены как nil.
Каждый день узнаю новое...
Anton911 вне форума Ответить с цитированием
Старый 01.05.2012, 18:36   #6
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Подозреваю, что ошибка в строке new(NewStep); или аналогичных. Рекомендую использовать AllocMem(SizeOf(TArena));

Ещё я бы сильно рекомендовал использовать классы вместо записей. Код получится гораздо лучше.

Например:

Код:
uses
  System.Contnrs;

type
  EMyError = class(Exception);
    EPlayerError = class(EMyError);
      EInvalidPlayerNameError = class(EPlayerError);
      ENoPlayerSet = class(EPlayerError);

  // Игрок
  TPlayer = class
  private
    FName: String;
  public
    constructor Create(const AName: String);

    property Name: String read FName;
  end;

  // Набор игроков
  TPlayers = class
  private
    FList: TObjectList;
    function GetItem(const AIndex: Integer): TPlayer;
    function GetCount: Integer;
  public
    constructor Create;
    destructor Destroy; override;

    procedure Add(const APlayer: TPlayer);
    procedure Delete(const AIndex: Integer);

    function IndexOf(const APlayerName: String): Integer;
    function Find(const APlayerName: String): TPlayer;

    property Count: Integer read GetCount;
    property Items[const AIndex: Integer]: TPlayer read GetItem; default;
  end;

  // Forward-описание
  TArena = class;

  // Шаг
  TStep = class
  private
    FArena: TArena;
    FIndex: Integer;

    FWhiteBlack: Integer;
    FCheckFrom: Integer;
    FCheckIn: Integer;
    function GetPlayer: TPlayer;
  public
    constructor Create(const AArena: TArena);

    property Arena: TArena read FArena;
    property Index: Integer read FIndex;

    property Player: TPlayer read GetPlayer;
    property WhiteBlack: Integer read FWhiteBlack;
    property CheckFrom: Integer read FCheckFrom;
    property CheckIn: Integer read FCheckIn;
  end;

  // Шаги
  TSteps = class
  private
    FList: TObjectList;
    function GetItem(const AIndex: Integer): TStep;
    function GetCount: Integer;
  public
    constructor Create;
    destructor Destroy; override;

    procedure Add(const AStep: TStep);
    procedure Delete(const AIndex: Integer);

    property Count: Integer read GetCount;
    property Items[const AIndex: Integer]: TStep read GetItem; default;
  end;

  // Арена
  TArena = class
  private
    FPlayers: TPlayers;
    FSteps: TSteps;
    FStartDate: TDateTime;
    FEndDate: TDateTime;
  public
    constructor Create;
    destructor Destroy; override;

    property Players: TPlayers read FPlayers;
    property Steps: TSteps read FSteps;

    property DateStart: TDateTime read FStartDate;
    property DateFinish: TDateTime read FEndDate;
  end;

  // Арены
  TArenas = class
  private
    FList: TObjectList;
    function GetItem(const AIndex: Integer): TArena;
    function GetCount: Integer;
  public
    constructor Create;
    destructor Destroy; override;

    procedure Add(const AArena: TArena);
    procedure Delete(const AIndex: Integer);

    property Count: Integer read GetCount;
    property Items[const AIndex: Integer]: TArena read GetItem; default;
  end;

procedure TForm1.FormCreate(Sender: TObject);
var
  Arenas: TArenas;
begin
  Arenas := TArenas.Create;
  try
    // Добавили две арены
    Arenas.Add(TArena.Create);
    Arenas.Add(TArena.Create);

    // Добавили каждой арене по 1 игроку
    Arenas[0].Players.Add(TPlayer.Create('Игрок №1'));
    Arenas[1].Players.Add(TPlayer.Create('Игрок №1'));

    // Три шага для первой арены
    TStep.Create(Arenas[0]);
    TStep.Create(Arenas[0]);
    TStep.Create(Arenas[0]);

    // Два шага для второй
    TStep.Create(Arenas[1]);
    TStep.Create(Arenas[1]);

    Caption := Arenas[0].Steps[0].Player.Name;
  finally
    // Удаляет все арены, шаги, игроков
    FreeAndNil(Arenas);
  end;
end;
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 01.05.2012, 18:36   #7
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

И реализация:

Код:
{ TPlayer }

constructor TPlayer.Create(const AName: String);
begin
  inherited Create;
  FName := AName;
end;

{ TPlayers }

constructor TPlayers.Create;
begin
  inherited Create;
  FList := TObjectList.Create(True);
end;

destructor TPlayers.Destroy;
begin
  FreeAndNil(FList);
  inherited Destroy;
end;

procedure TPlayers.Add(const APlayer: TPlayer);
begin
  FList.Add(APlayer);
end;

procedure TPlayers.Delete(const AIndex: Integer);
begin
  FList.Delete(AIndex);
end;

function TPlayers.IndexOf(const APlayerName: String): Integer;
var
  X: Integer;
begin
  Result := -1;
  for X := 0 to FList.Count - 1 do
    if Items[X].Name = APlayerName then
    begin
      Result := X;
      Break;
    end;
end;

function TPlayers.Find(const APlayerName: String): TPlayer;
var
  Ind: Integer;
begin
  Ind := IndexOf(APlayerName);
  if Ind < 0 then
    raise EInvalidPlayerNameError.CreateFmt('Не найден игрок с именем %s', [APlayerName]);

  Result := Items[Ind];
end;

function TPlayers.GetCount: Integer;
begin
  Result := FList.Count;
end;

function TPlayers.GetItem(const AIndex: Integer): TPlayer;
begin
  Result := TPlayer(FList[AIndex]);
end;

{ TStep }

constructor TStep.Create(const AArena: TArena);
begin
  inherited Create;
  FArena := AArena;
  FArena.Steps.Add(Self);
end;

function TStep.GetPlayer: TPlayer;
begin
  if FArena.Players.Count = 0 then
    raise ENoPlayerSet.Create('Не заданы игроки');
  Result := FArena.Players[0];
end;

{ TSteps }

constructor TSteps.Create;
begin
  inherited;
  FList := TObjectList.Create(True);
end;

destructor TSteps.Destroy;
begin
  FreeAndNil(FList);
  inherited;
end;

procedure TSteps.Add(const AStep: TStep);
begin
  FList.Add(AStep);
end;

procedure TSteps.Delete(const AIndex: Integer);
begin
  FList.Delete(AIndex);
end;

function TSteps.GetCount: Integer;
begin
  Result := FList.Count;
end;

function TSteps.GetItem(const AIndex: Integer): TStep;
begin
  Result := TStep(FList[AIndex]);
end;

{ TArena }

constructor TArena.Create;
begin
  inherited Create;
  FPlayers := TPlayers.Create;
  FSteps := TSteps.Create;
end;

destructor TArena.Destroy;
begin
  FreeAndNil(FPlayers);
  FreeAndNil(FSteps);
  inherited Destroy;
end;

{ TArenas }

constructor TArenas.Create;
begin
  inherited Create;
  FList := TObjectList.Create(True);
end;

destructor TArenas.Destroy;
begin
  FreeAndNil(FList);
  inherited;
end;

procedure TArenas.Add(const AArena: TArena);
begin
  FList.Add(AArena);
end;

procedure TArenas.Delete(const AIndex: Integer);
begin
  FList.Delete(AIndex);
end;

function TArenas.GetCount: Integer;
begin
  Result := FList.Count;
end;

function TArenas.GetItem(const AIndex: Integer): TArena;
begin
  Result := TArena(FList[AIndex]);
end;
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 03.05.2012, 08:49   #8
Anton911
Форумчанин
 
Аватар для Anton911
 
Регистрация: 23.08.2011
Сообщений: 171
По умолчанию

Поразмышляю над этим.
Каждый день узнаю новое...
Anton911 вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Record SasukeUciha Паскаль, Turbo Pascal, PascalABC.NET 0 16.10.2011 12:01
Record! .K.E.P. Паскаль, Turbo Pascal, PascalABC.NET 1 17.12.2010 21:56
В чём различие записей Record от Packed Record? Terran Общие вопросы Delphi 7 08.06.2010 17:14
Record / Packed Record Alex Cones Общие вопросы Delphi 7 11.11.2009 10:43
my Record subsonic Общие вопросы Delphi 5 09.02.2009 15:20