Резултати от 1 до 13 от общо 13

Проблем със "Set of ..." при Delphi 5

Сподели във Facebook Сподели в Twitter Изпрати на Email Сподели в LinkedIn
  1. SAGE
    Guest
    #1

    Проблем със "Set of ..." при Delphi 5

    Накратко проблема е с променлива от тип "set of...." с 16..31 елемента и като искам да я инициализирам чрез ":=[]", то вместо да стане "[]" става [elm24..elem30]
    Направих и следния тест:

    Код:
    type 
    Test=(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32); 
    TTestSet= set of Test; 
    TTestSet1= set of 1..16;
    TTestSet2= set of 1..32; 
    var 
    TestSet:TTestSet; 
    TestSet1:TTestSet1; 
    TestSet2:TTestSet2; 
    begin 
    TestSet:=[];//тук се получава все едно съм задал TestSet:=[t24..t30]; 
    TestSet1:=[];//тук се получава все едно съм задал TestSet1:=[23..29]; 
    TestSet2:=[];//тук всичко е нормално 
    .................... 
    end;
    Нулиране на TestSet получавам само така:
    Fillchar(TestSet,SizeOf(TestSet),0);
    Но след това проверката "TestSet<>&#91;]" винаги дава True, а "TestSet=&#91;]" - False ????
    Лошото е, че на много места използвам такъв тип променливи и ако трябва да променям всички или да ги проверявам за проблеми ще ми отнеме много време. Въпросната грешка я открих случайно при Debug на част от кода.

    След още тестове установих следното:
    TTestSet2= set of 1..15;//дължина(SizeOf) 2 байта -> няма проблеми
    TTestSet3= set of 1..16;//дължина(SizeOf) 4???? байта -> ИМА проблеми
    TTestSet4= set of 1..31;//дължина(SizeOf) 4 байта -> ИМА проблеми
    TTestSet5= set of 1..39;//дължина(SizeOf) 5 байта -> няма проблеми
    TTestSet6= set of 1..47;//дължина(SizeOf) 6 байта -> няма проблеми
    TTestSet7= set of 1..55;//дължина(SizeOf) 7 байта -> няма проблеми
    TTestSet32= set of 1..255;//дължина(SizeOf) 32 байта -> няма проблеми

    След инициализиране:
    TestSet3:=&#91;];
    TestSet4:=&#91;];
    то ShowMessage('ts3='+IntToStr(Longint(TestSet3))+';' +'ts4='+IntToStr(Longint(TestSet4)));
    ми връща: "ts3=1065353216;ts4=1065353216"

    =>проблема е само при 4 байтовите set-ове. ?

    Чудя се аз ли бъркам някъде или има проблем с Delphi 5?

    След като направих Copy->Paste на "тестовия" код на друго място в програмата, то там всичко си работеше по нормалния начин??? Единствено дължината на TestSet3 пак беше 4 байта вместо 3???
    В имената на "тестовите" променливи и в начина им на дефиниране и използване няма никаква разлика на двете места, но защо се получават различни резултати?
    Възможно ли е някаква директива на компилатора да предизвиква тези аномалии? (доста комбинации направих и с директивите но проблема си остава)
    Единственото логично обяснение според мен е, че понякога "&#91;]" не е празно и затова при проверката "if TestSet<>&#91;]" и при инициализиране чрез "TestSet:=&#91;]" не се получава това което очаквам.
    Вече се замислям дали начина ми на работа с множества не е погрешен. И как да съм сигурен на другите места в програмата какво се случва и дали всичко работи както трябва?
    Моля за помощ и благодаря предварително на тези, които ще помогнат.
    Може и да почерпя някой път.

    Благодаря и на тези, които са прочели написаното, защото май не се получи "накратко".

  2.  
     
  3. Member Аватара на kamenf
    Тук е от
    Feb 2005
    Мнения
    799
    #2

    Re: Проблем със "Set of ..." при Delphi 5

    Имам инсталирано само Delphi 7 и под него горния код работи както се очаква. Не намирам подобна публикувана грешка за Delphi 5 или по-ранни. Сигурен съм обаче, че ако нещо такова имаше, самият аз щях да изплача.

    Сигурно ли е, че тези грешки ги получаваш в "чиста" програма - т.е. ползваща само System и никакви други юнити? Най-добре - само горния код. Питам, защото Delphi компилатора "скрито" дефинира:
    var
    Empty1: set of byte = &#91;];
    Empty2: set of word = &#91;];
    Empty4: set of longword = &#91;];
    ...
    и т.н. до 32 байта.
    и ползва горните променливи (всъщност инициализирани константи) за присъединяване и сравняване с празно множество на променлива заемаща съответната дължина байтове и е възможно някой друг код без да иска да променя паметта на точно някоя от тези константи (в твоя случай май е точно тази с дължина 4 байта).

    Както забелязваш, не се дефинира променлива с три байта и това е нарочно - за оптимизация. Set of 1..16 заема 17 бита - когато е числова областта на множеството, Delphi ползва битовете със съответните номера (set of 16..33 е 34 бита) - ето защо 1..16 заема 3, което значи, че Delphi ползва 4 байта.

    Виж също какво ще стане ако пишеш TestSet:=(TestSet*[t1]) - [t1]; - би трябвало да даде празно множество. Но го гледай в дебугера или в програмата като интеджер.

    Пробвай също така да изключищ оптимизациите - {$OPTIMIZATION OFF} - току-виж това бил проблема.

  4. Junior Member
    Тук е от
    Mar 2006
    Мнения
    134
    #3

    Re: Проблем със "Set of ..." при Delphi 5

    Пробвай също и:
    Project \ Options \ Compiler \ Record Field Alignment - по дефол е 8 байта....

  5. SAGE
    Guest
    #4

    Re: Проблем със "Set of ..." при Delphi 5

    kamenf и The_Wizard благодаря ви за отговорите.

    @The_Wizard ,
    "Aligned record fields" при мен е винаги изключено, защото проекта е още от Delphi 1.

    Цитат Първоначално публикувано от kamenf
    ............
    Виж също какво ще стане ако пишеш TestSet:=(TestSet*[t1]) - [t1]; - би трябвало да даде празно множество. Но го гледай в дебугера или в програмата като интеджер.

    Пробвай също така да изключищ оптимизациите - {$OPTIMIZATION OFF} - току-виж това бил проблема.
    @kamenf,
    При "TestSet:=(TestSet*[t1]) - [t1];" - дава празно множество но проверката "TestSet=&#91;]" връща "False".
    Оптимизацията я включвам само при компилация "за клиенти".
    По-горе съм написал, че този проблем го има само на някои места в проекта, т.е. в "чиста" програма го няма проблема.
    Затова мисля, че вероятно(99% ) е това което казваш:
    Цитат Първоначално публикувано от kamenf
    ..............
    Delphi компилатора "скрито" дефинира:
    var
    Empty1: set of byte = &#91;];
    Empty2: set of word = &#91;];
    Empty4: set of longword = &#91;];
    ...
    и т.н. до 32 байта.
    и ползва горните променливи (всъщност инициализирани константи) за присъединяване и сравняване с празно множество на променлива заемаща съответната дължина байтове и е възможно някой друг код без да иска да променя паметта на точно някоя от тези константи (в твоя случай май е точно тази с дължина 4 байта).
    .................
    Не успях да намеря къде се дефинират "Empty1...Empty32", пък и променливи с тези имена със сигурност не използвам. Вероятно в Delphi 5 не се казват така и ще ти бъда благодарен ако може да ми кажеш къде да търся повече информация за set-вете в Delphi 5 или къде се дефинират "Empty1..Empty32".

  6. Member Аватара на kamenf
    Тук е от
    Feb 2005
    Мнения
    799
    #5

    Re: Проблем със "Set of ..." при Delphi 5

    Това беше условно - няма да намериш тези дефиниции - затова казах "скрито". Но можеш да погледнеш с CPU дебугера асемблерския код на въпросното присъединяване или сравнение и после по адреса измъкнат от там да инсталираш хардуерен брейкпойнт по запис в памет и така да хванеш кой я променя.

  7. SAGE
    Guest
    #6

    Re: Проблем със "Set of ..." при Delphi 5

    Цитат Първоначално публикувано от kamenf
    Това беше условно - няма да намериш тези дефиниции - затова казах "скрито". Но можеш да погледнеш с CPU дебугера асемблерския код на въпросното присъединяване или сравнение и после по адреса измъкнат от там да инсталираш хардуерен брейкпойнт по запис в памет и така да хванеш кой я променя.
    Жалко, щеше да е много по-лесно, ако не беше "скрито".
    С асемблер не съм се занимавал от 1990г. и ще те помоля за "малко" помощ.
    Ето какво ми дава CPU дебугера:
    Код:
    problem.pas.743:	TestSet:=&#91;];
    00A252CC A1BC63A200    mov eax,[име_на_процедурата + $2CC8]
    00A252D1 8945C4      mov [ebp-$3c],eax
    problem.pas.744:	TestSet2:=&#91;];
    00A252D4 66A1BC63A200   mov ax,[$00a263bc]
    00A252DA 668945BE     mov [ebp-$42],ax
    problem.pas.745:	TestSet3:=&#91;];
    00A252DE A1BC63A200    mov eax,[име_на_процедурата + $2CC8]
    00A252E3 8945BA      mov [ebp-$46],eax
    problem.pas.746:	TestSet5:=&#91;];
    00A252E6 8B05E063A200   mov eax,[име_на_процедурата + $2CEC]
    00A252EC 8945B1      mov [ebp-$4f],eax
    00A252EF 8A05E463A200   mov al,[име_на_процедурата + $2CF0]
    00A252F5 8845B5      mov [ebp-$4b],al
    Код:
    var
    TestSet= set of (t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,
             t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32);
    TestSet2= set of 1..15;
    TestSet3= set of 1..16;
    TestSet5= set of 1..39;
    Проблема е при "problem.pas.743: TestSet:=&#91;];" и "problem.pas.745: TestSet3:=&#91;];"
    Предполагам, че това "[име_на_процедурата + $2CC8]" е някакъв относителен адрес за мястото, където се намира "&#91;]", но:
    Как "да инсталирам хардуерен брейкпойнт по запис в паметта" при Delphi 5? (Никога не съм използвал тази възможност и дали ще може при Delphi 5)
    Какъв е адреса на "&#91;]"?

  8.  
     
  9. Junior Member
    Тук е от
    Mar 2006
    Мнения
    134
    #7

    Re: Проблем със "Set of ..." при Delphi 5

    Борланд казва това:
    Set types
    A set is a bit array where each bit indicates whether an element is in the set or not. The maximum number of elements in a set is 256, so a set never occupies more than 32 bytes. The number of bytes occupied by a particular set is equal to
    (Max div 8) - (Min div 8) + 1
    where Max and Min are the upper and lower bounds of the base type of the set. The byte number of a specific element E is
    (E div 8) - (Min div 8)
    and the bit number within that byte is
    E mod 8
    where E denotes the ordinal value of the element.

    може да се окаже че си открил бъг......

  10. Member Аватара на kamenf
    Тук е от
    Feb 2005
    Мнения
    799
    #8

    Re: Проблем със "Set of ..." при Delphi 5

    Така... ще се опитам по памет. Първо натискаш F8 - да стартира програмата, но да спре на първата инструкция. Второ: от менюто View\Debug Windows\Breakpoints трябва да се показва прозореца Breakpoints. Ако не се показва от там - намери от къде точно се показва. В прозореца Breakpoints - десен бутон на мишката и "Add -> Data Breakpoint". Излиза диалог в който трябва да въведеш адрес от паметта, който искаш да се следи и колко байта да се следят - достатъчно е да въведеш само адреса и големината и ще прекъсва на всяка инструкция която променя паметта в този адрес. От твоя пример адреса (на &#91;]) е [име_на_процедурата + $2CC8] или @(PChar(@име_на_процедурата) + $2CC8)^ - последното можеш да го видиш колко е в "Evaluate/Modify..." диалога (обикновено се пуска с Ctrl+F7), или спри на реда "mov eax,[име_на_процедурата + $2CC8]" и отгоре на CPU прозореца трябва да имаш редче от рода на "[$00123456] = $00000000" (в квадратните скоби е адреса на въпросното &#91;]). Вивеждаш за Length - 4. После пускаш програмата да върви и гледай кога и защо прекъсва - на накое от тези места трябва да е проблема.

  11. SAGE
    Guest
    #9

    Re: Проблем със "Set of ..." при Delphi 5

    Цитат Първоначално публикувано от kamenf
    Така... ще се опитам по памет. Първо ....
    @kamenf, явно имаш много добра памет.
    Всичко е точно така, както си го описал. Но сигурно аз бъркам някъде, защото при "Add Data Breakpoint" за адреса който намирам не се създава Breakpoint, мога да създам само "Address Breakpoint".
    Сутринта ще опитам пак, че този проблем със "set-овете" ме дразни като "муха в стая" и докато не разбера каква точно е причината ще ми "бръмчи" в главата.

  12. Member Аватара на kamenf
    Тук е от
    Feb 2005
    Мнения
    799
    #10

    Re: Проблем със "Set of ..." при Delphi 5

    Ако така не стане (а явно няма, или поне не при Delphi 5, защото доколкото виждам от асемблера, паметта е в участъка на кода), можеш да опиташ и друго - ръчния метод - като намериш адреса на 4-байтовия &#91;] по един от горните методи, отвори си "Watch List"-a (View\Debug Windows\Watches) и в него - десен бутен -> Add Watch -> "PInteger($онзи_адрес)^" (трябва да показва 0 като стойност), после изпълнявай програмата на порции да хванеш кога ще престане да показва 0 и така лека-полека изолирай частта от кода, който променя тази памет. Разбира се, същото можеш да го гледаш и в CPU прозореца (в долната рамка - Goto Address...), ама не е толкова изолирано.

    А ако не ти се занимава, може да направиш и един генерален уъркараунд (баааси, как изглежда на кирилица )- декларирай си константа (или константи - за всеки множествен тип който използваш):
    const
    Empty: TWantedSet = &#91;];
    и после я(ги) замени навсякъде в кода, където използваш &#91;].

  13. Junior Member
    Тук е от
    Mar 2006
    Мнения
    134
    #11

    Re: Проблем със "Set of ..." при Delphi 5

    малко трудно ще сложиш брекпойнт на мемори менаджера, но както и да е....
    тука има нещо свързано с ord типевете ми се струва.

  14.  
     
  15. SAGE
    Guest
    #12

    Re: Проблем със "Set of ..." при Delphi 5

    Май ще се окаже "мисия невъзможна" откриването на проблема.
    Чрез "Add Watch" на "PInteger($00A2691C)^", след това при стартиране с F8 на програмата и спиране на първата инструкция в "dpr" файла (преди да се изпълни "Application.Initialize;"), то вече в адреса на "&#91;]" е заредена стойността, която по-късно се присвоява при "нулиране" на TestSet.
    В друга процедура в която съм копирал същия "тестов код" адреса на "&#91;]" е друг и за него всичко е нормално в "Add Watch" на "PInteger($006EE9B8)^".
    Кой и кога е записал нещо в тази клетка от паметта остава в тайна.
    Когато ми остане повече свободно време ще си дефинирам константи за изпозваните видове set-ове и ще заменя навсякъде "&#91;]" със съответната константа, че вече доста време отделих на този проблем.

    @kamenf, като гледам часа в който пишеш във форума, май наистина "дочакваш утрото", т.е. това, което си написал като подпис е вярно.

    Цитат Първоначално публикувано от The_Wizard
    малко трудно ще сложиш брекпойнт на мемори менаджера, но както и да е....
    тука има нещо свързано с ord типевете ми се струва.
    @The_Wizard, проблем със сигурност има, но защо се случва на мен и то в момент в който имам много задачи и всички са с краен срок "вчера" .

  16. Junior Member
    Тук е от
    Mar 2006
    Мнения
    134
    #13

    Re: Проблем със "Set of ..." при Delphi 5

    закон за всемирната гадост......
    Драсни маил на супорта на борланд и им обясни проблема.

Сподели във Facebook Сподели в Google Plus Сподели в Twitter Изпрати на Email Сподели в LinkedIn

Подобни теми

  1. Отговори: 29
    Последно: 29-01-23, 16:48
  2. Проблем с LG 42LB700v "out of memory.app is closed""
    От mr_spek във форум LG телевизори
    Отговори: 5
    Последно: 30-05-15, 11:02
  3. Отговори: 4
    Последно: 15-01-12, 23:07
  4. Отговори: 6
    Последно: 15-09-10, 17:53
  5. Отговори: 13
    Последно: 07-06-06, 10:04

SetCombG.com
SetCombG.com е портален сайт и Форум за битова техника, телевизори, климатици, лаптопи и смартфони, създаден през 1999 година.
Заедно сме над 20 години!
Следвай ни
Горе