Вопросы программирования на Free Pascal, использования компилятора и утилит.
Модератор: Модераторы
SovNarKom
постоялец
Сообщения: 389 Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]
Контактная информация:
Сообщение
SovNarKom » 26.06.2005 23:10:38
Это так и будет или лечится включением чего-нибудь?
Сразу скажу, что в Delphi всё ОК.
А FPC 2.0.0, 1.9.8 такая вот ерунда (в процессе работы acess violation...):
Код: Выделить всё
program Project1; type TBaseC = class a,b,c: Integer; arra: Array of Cardinal; end; TOneClass = class(TBaseC) arr: Array of Cardinal; end; TMainClass = class A,B,C: Array of TBaseC; end; var SSS: TMainClass; begin SSS:=TMainClass.Create; SetLength(SSS.A,1); SSS.A[0]:=TBaseC.Create; // кстати если TOneClass.Create - OK SetLength(TOneClass(SSS.A[0]).arr, 100000); // Хана! <-------------------------------- end.
Sniper
постоялец
Сообщения: 472 Зарегистрирован: 28.05.2005 13:02:42
Сообщение
Sniper » 27.06.2005 00:01:01
А в чём выражается сие ХАНА? У меня в 2.1.1 вроде бы всё нормально.. Прочитал пост внимательнее: у меня никаких AV не наблюдается
Romtek
постоялец
Сообщения: 190 Зарегистрирован: 22.05.2005 12:29:35
Откуда: Рамат Ган
Контактная информация:
Сообщение
Romtek » 27.06.2005 01:12:03
Присмотревшись к типам:
Код: Выделить всё
type TBaseC = class a,b,c: Integer; arra: Array of Cardinal; end; TOneClass = class(TBaseC) arr: Array of Cardinal; end; TMainClass = class A,B,C: Array of TBaseC; end;Я подозреваю, что дело в именах
A, B, C . Они перекрываются, хотя не знаю, верно ли это. Назови их другим именами.
SovNarKom
постоялец
Сообщения: 389 Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]
Контактная информация:
Сообщение
SovNarKom » 27.06.2005 11:03:21
Romtek Неееее... они не перекрываются.
Тест №2 - > в 1.9.8 из под Лазаря runtime error 201, в 2.0.0 IDE - OK
Код: Выделить всё
program Project1; type pTArr = ^TArr; TArr = Array [0..0] of Byte; var SSS: pTArr; i: Integer = 99; begin GetMem(SSS, 100000); SSS^[i]:=99; // < --------------------------- runtime error 201 FreeMem(SSS); end.И этот метод не сработал...
Uniser
новенький
Сообщения: 46 Зарегистрирован: 13.05.2005 23:13:57
Откуда: Украина, Полтава
Сообщение
Uniser » 27.06.2005 11:33:37
Смотри чего делаешь (?):
Код: Выделить всё
SSS.A[0]:=TBaseC.Create; // кстати если TOneClass.Create - OK SetLength(TOneClass(SSS.A[0]).arr, 100000); // Хана!В массиве A могут храниться как TBaseC, так и его наследники TOneClass, но об этом должен помнить сам программист. Если ты создал TBaseC, а потом пытаешься найти в нём поле arr, объявленное в наследнике, так чего ты хочешь от Паскаля?!
Конечно нарушение!!!
SovNarKom
постоялец
Сообщения: 389 Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]
Контактная информация:
Сообщение
SovNarKom » 27.06.2005 11:37:36
Uniser Ты прав,
НО в Delphi как-то работает... А ещё тут говорили что в FPC 2.1.1 :unsure:
Вот для чистоты эксперимента:
Код: Выделить всё
program Project1; {$H+} type TBaseC = class end; TOneClass = class(TBaseC) Ax: Array of Cardinal; Str: String; Card: Cardinal; end; TMainClass = class A: TBaseC; end; var SSS: TMainClass; begin SSS:=TMainClass.Create; {$DEFINE XAHA} {$IFDEF XAHA} SSS.A:=TBaseC.Create; TOneClass(SSS.A).Card:=1234567890; // OK !!!!!!!!!!! <-------- TOneClass(SSS.A).Str:='UPS'; // XAHA <-------------------------------- SetLength(TOneClass(SSS.A).Ax, 100000); // XAHA <-------------------------------- {$ENDIF} SSS.A:=TOneClass.Create; TOneClass(SSS.A).Card:=1234567890; // OK TOneClass(SSS.A).Str:='UPS';// OK SetLength(TOneClass(SSS.A).Ax, 100000); // OK end.
Uniser
новенький
Сообщения: 46 Зарегистрирован: 13.05.2005 23:13:57
Откуда: Украина, Полтава
Сообщение
Uniser » 27.06.2005 11:38:27
В Паскале не проверял, но в Делфи можно так:
Код: Выделить всё
if SSS.A[0] is TOneClass then SetLength(TOneClass(SSS.A[0]).arr, 100000) else WriteLn('Это другой класс.');
Uniser
новенький
Сообщения: 46 Зарегистрирован: 13.05.2005 23:13:57
Откуда: Украина, Полтава
Сообщение
Uniser » 27.06.2005 11:43:02
Может в Делфи не проверяется ошибка? Не может программа создать TOneClass, когда её просят создать TBaseC. Пробовал-ли заполнять массив созданный в Делфи?
SovNarKom
постоялец
Сообщения: 389 Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]
Контактная информация:
Сообщение
SovNarKom » 27.06.2005 11:43:24
Uniser Можно, но мне это не поможет
Я код ^ поправил малость - если у наследника поле имеет фиксированый размер - всё нормально.
SovNarKom
постоялец
Сообщения: 389 Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]
Контактная информация:
Сообщение
SovNarKom » 27.06.2005 11:45:11
Uniser У меня в Delphi на этом многое(!) работает и ни разу не сваливалось в acess violation... А это просто пример...
Uniser
новенький
Сообщения: 46 Зарегистрирован: 13.05.2005 23:13:57
Откуда: Украина, Полтава
Сообщение
Uniser » 27.06.2005 11:49:36
Ошибка не выскакивает, но ты всё равно портишь информацию в памяти.
Проблема связана с
ограниченностью функции проверяющей нарушение доступа, которая не видит нарушения в
Код: Выделить всё
SSS.A:=TBaseC.Create; TOneClass(SSS.A).Card:=1234567890; На самом деле таким присваиванием ты можешь испортить значения в других объектах, также как запросто можешь потерять его в результате другой команды.
SovNarKom
постоялец
Сообщения: 389 Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]
Контактная информация:
Сообщение
SovNarKom » 27.06.2005 11:51:39
Uniser Скорее всего ты прав...
Uniser
новенький
Сообщения: 46 Зарегистрирован: 13.05.2005 23:13:57
Откуда: Украина, Полтава
Сообщение
Uniser » 27.06.2005 11:51:55
Если у наследника будет много полей то в конце концов таким присваиванием
Код: Выделить всё
SSS.A:=TBaseC.Create; TOneClass(SSS.A).Card:=1234567890; ты получишь AV
SovNarKom
постоялец
Сообщения: 389 Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]
Контактная информация:
Сообщение
SovNarKom » 27.06.2005 11:55:59
Да вспомнил! В Delphi тоже были проблемы, я отказался от динамических массивов... да это конечно правильно при создании класса памяти выделяется только для него, да. А вот по поводу второго примера?
Uniser
новенький
Сообщения: 46 Зарегистрирован: 13.05.2005 23:13:57
Откуда: Украина, Полтава
Сообщение
Uniser » 27.06.2005 12:11:02
У меня ни в Делфи ни в Лазарусе ни в Паскале не выдаёт никаких ошибок.