![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
непонятная ошибочка [D7, WinXP]
ак © (2006-08-15 14:49:00)Здравствуйте, уважаемые Мастера Delphi. Прошу вас помочь по следующему вопросу. При установке значения константы BASE_MAX_WIDTH или BASE_MAX_HEIGHT >= 25 программулька либо вообще не запускается (выдаёт сообщение об ошибке доступа к блоку памяти (а asm я не знаю)), либо запускается, но закрывается с сообщением примерно такого же рода. Скорее всего, конечно, при таких ошибках можно сказать что "парю" я сам, только вот где? Подскажите, plz. Привожу прогу (без сокращений, прога по учебной рассылке создания ролевой игры):
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls;
type
Tmainform = class(TForm)
strgridMain: TStringGrid;
btGenerateNewMap: TButton;
procedure FormCreate(Sender: TObject);
procedure GenerateNewMap;
procedure strgridMainDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
procedure btGenerateNewMapClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
const BASE_MAX_WIDTH = 50;
BASE_MAX_HEIGHT = 50;
VISIBLE_MAP_WIDTH = 2;
VISIBLE_MAP_HEIGHT = 2;
MAX_WIDTH = BASE_MAX_WIDTH + 2*VISIBLE_MAP_WIDTH;
MAX_HEIGHT = BASE_MAX_HEIGHT + 2*VISIBLE_MAP_HEIGHT;
type TTileType = (ttGrass, ttGround, ttTree, ttStoune, ttEndMap);
TTileRec = record
Cells: array [1..MAX_WIDTH, 1..MAX_HEIGHT] of TTileType;
IsVisible: boolean
end;
var
mainform: Tmainform;
TileRec: TTileRec;
implementation
{$R *.dfm}
procedure Tmainform.GenerateNewMap;
var x, y, cause_koef: integer;
leftMapPos, rightMapPos, topMapPos, bottomMapPos: integer;
begin
// это просто вспом. переменные, чтоб вам читабельнее было
leftMapPos := MAX_WIDTH - BASE_MAX_WIDTH - VISIBLE_MAP_WIDTH;
rightMapPos := MAX_WIDTH - VISIBLE_MAP_WIDTH - 1;
topMapPos := MAX_HEIGHT - VISIBLE_MAP_HEIGHT - 1;
bottomMapPos := MAX_HEIGHT - BASE_MAX_HEIGHT - VISIBLE_MAP_HEIGHT;
randomize;
for x:=0 to MAX_WIDTH-1 do
for y:=0 to MAX_HEIGHT-1 do
if (x in [leftMapPos..rightMapPos]) and (y in [bottomMapPos..topMapPos]) then
begin
cause_koef := random(100);
case cause_koef of
0..5: TileRec.Cells[x, y] := ttStoune;
6..16: TileRec.Cells[x, y] := ttGround;
17..47: TileRec.Cells[x, y] := ttTree;
48..100: TileRec.Cells[x, y] := ttGrass;
end;
end
else TileRec.Cells[x, y] := ttEndMap;
end;
procedure Tmainform.FormCreate(Sender: TObject);
begin
//
with strgridMain do
begin
RowCount := MAX_HEIGHT;
ColCount := MAX_WIDTH;
DefaultColWidth := (Width div MAX_WIDTH) - 2;
DefaultRowHeight := (Height div MAX_HEIGHT) - 2;
end;
GenerateNewMap;
end;
procedure Tmainform.strgridMainDrawCell(Sender: TObject; ACol,
ARow: Integer; Rect: TRect; State: TGridDrawState);
var GridCellRect: TRect;
begin
with strgridMain do
begin
GridCellRect := CellRect(ACol, ARow);
case TileRec.Cells[ARow, ACol] of
ttGrass: Canvas.Brush.Color := clGreen;
ttGround: Canvas.Brush.Color := clRed;
ttTree: Canvas.Brush.Color := clYellow;
ttStoune: Canvas.Brush.Color := clGray;
ttEndMap: Canvas.Brush.Color := clBlack
end;
Canvas.FillRect(GridCellRect)
end;
end;
end.
ак (2006-08-15 15:57:00) [1]Теоритически цикл обработки элементов массива
for i:=0 to count-1 ...
должен работать быстрее, чем
for i:=1 to count ...
так как для расчета физического адреса элемента в памяти требуется меньшее кол-во операций. Но в действительности разницы обычно нет.
Вот я типа об этом и говорил (только своими словами :-) ).
ак (2006-08-15 15:53:00) [2]Что за бред ?
Что ты называешь "инициализацией" в дан.случае и для чего ее "устанавливать в ноль" при for i:=1 to .. ?
Да вы меня просто неправильно поняли. Thank for help!
Loginov Dmitry (2006-08-15 15:51:00) [3]> в смыле, быстродействием или ещё чем либо
Теоритически цикл обработки элементов массива
for i:=0 to count-1 ...
должен работать быстрее, чем
for i:=1 to count ...
так как для расчета физического адреса элемента в памяти требуется меньшее кол-во операций. Но в действительности разницы обычно нет.
Сергей М. (2006-08-15 15:44:00) [4]
> Веть переменная i в любом случае должна быть инициализирована
> - установлена в ноль, а её нач. значение не важно.
Что за бред ?
Что ты называешь "инициализацией" в дан.случае и для чего ее "устанавливать в ноль" при for i:=1 to .. ?
ак (2006-08-15 15:40:00) [5]Спасибо ещё раз всем. Извините что отнял время по такому ерундовому вопросу, впредь буду внимательнее. А может кто подскажет чем, собственно, отличается конструкция for i:=0 to count-1 от for i:=1 to count (в смыле, быстродействием или ещё чем либо ). Веть переменная i в любом случае должна быть инициализирована - установлена в ноль, а её нач. значение не важно.
Сергей М. (2006-08-15 15:30:00) [6]
> верно ведь?
Нет, неверно.
Это дело случая.
ак (2006-08-15 15:26:00) [7]Да зачем там ассемблер?
Внимательнее код посмотрите:
Cells: array [1..MAX_WIDTH, 1..MAX_HEIGHT] of TTileType;
...
for x:=0 to MAX_WIDTH-1 do
for y:=0 to MAX_HEIGHT-1 do
Range checking наверняка выключен, и программа это молча проглатывает
Дам-с ..., если дело в этом то я балбес. Но в таком случае ошибка вылазила бы всегда, при любых значениях константы, верно ведь?
ак (2006-08-15 15:23:00) [8]ставишь bp на начало цикла и всё, потом когда программа до туда дойдёт она там и остановиться. Пошаговая отладка называется.
Да я просо не понимаю как такое вообще может быть, почему при 10-ти - всё нормально, чуть-больше - не работает. Какое значение может иметь число, да хоть миллион поставлю - должно ведь работать. Delphi ведь не какая-нибудь лажовая среда разработки (с этим наверное все согласны :-) ). Ладно, спасибо tesseract`у и Сергею М за ответы.
Плохиш (2006-08-15 15:23:00) [9]
> ак (15.08.06 14:49)
Нумерация строк начинается с нуля, поэтому первый вызов strgridMainDrawCell произойдёт для ячейки [0, 0]. Дальше сам додумывай.
DrPass (2006-08-15 15:22:00) [10]Да зачем там ассемблер?
Внимательнее код посмотрите:
Cells: array [ 1..MAX_WIDTH, 1..MAX_HEIGHT] of TTileType;
...
for x:=0 to MAX_WIDTH-1do
for y:=0 to MAX_HEIGHT-1do
Range checking наверняка выключен, и программа это молча проглатывает
tesseract (2006-08-15 15:17:00) [11]
> ак (15.08.06 15:15) [7]
Какой ассемблер ?????
ставишь bp на начало цикла и всё, потом когда программа до туда дойдёт она там и остановиться. Пошаговая отладка называется.
ак (2006-08-15 15:15:00) [12]а запустить отладчик и гнянуть, что на 50 шаге происходит?
я же говорю, я совсем не разбираюсь в асемблере, мне там ничего не понятно. Может кто у себя это дело запустить попробует, это ведь не долго - форма и stringgrid ...
tesseract (2006-08-15 15:12:00) [13]а запустить отладчик и гнянуть, что на 50 шаге происходит?
ак (2006-08-15 15:08:00) [14]см. меню Search -> Find Error !!
Это я обязательно посмотрю. Просто мне и самому непонятна проблема, если BASE_MAX_WIDTH равно, скажем, 10, 11, ... - то всё нормально, если число немногим больше (порядка 50-ти, например), то ошибка. В чём в принципе может быть загвоздка?
Сергей М. (2006-08-15 15:03:00) [15]см. меню Search -> Find Error !!
Использование этой фичи не требует знания асма, если ошибка именно в твоем коде.
ак (2006-08-15 14:59:00) [16]> В сообщении об ошибке фигурирует адрес, его и следует использовать для поиска строки, вызвавшей ошибку.
да я asm-ра не знаю
Сергей М. (2006-08-15 14:58:00) [17]
> только вот где?
В сообщении об ошибке фигурирует адрес, его и следует использовать для поиска строки, вызвавшей ошибку.
см. меню Search -> Find Error ..
ак (2006-08-15 14:58:00) [18]Вопрос конечно не "ахти", но может поможете ... Ple-e-e-a-a-a-se.