Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.10.10;
Скачать: [xml.tar.bz2];

Вниз

New()   Найти похожие ветки 

 
][ncognito   (2004-09-22 00:28) [0]

Ув. господа, подскажите, как узнать был ли над указателем проведена процедура New();


 
Defunct ©   (2004-09-22 00:33) [1]

Var P: Pointer = nil;

1. if P <> Nil Then <был создан, не обязательно New>

2. Try
    P^ := ....
  Except
    < не был создан >
  End;


 
GuAV ©   (2004-09-22 00:52) [2]

В наиболее общем случае никак и незачем.


 
jack128 ©   (2004-09-22 01:14) [3]

Defunct ©   (22.09.04 0:33) [1]
Try
   P^ := ....
 Except
   < не был создан >
 End;

это гарантии не дает..


 
Defunct ©   (2004-09-22 01:16) [4]

GuAV ©   (22.09.04 00:52) [2]
это почему же?

Вы что ни разу не пользовались хотя бы одной из этих конструкций:
1. If Assigned( P ) Then ...
2. If P <> Nil Then ...
3. Try
    P.Field := ..
  Except
  End;


Все они проверяют условие существования данных под указателем, а значит показывают, что (говоря словами автора вопроса) использовалась процедура New.


 
GuAV ©   (2004-09-22 01:40) [5]

Defunct ©   (22.09.04 01:16) [4]

> Все они проверяют условие существования данных под указателем

Первые две проверяют указатель на неравенство nil, но он может быть и не равен nil но и не указывать куда либо. например мусор в стеке или уже освобождённый объект/структура/др.

> а значит показывают, что (говоря словами автора вопроса)
> использовалась процедура New.

Есть и другие способы достижения того чтобы указател укарывал на данные, напимер @ оператор.

> 3. Try
>     P.Field := ..
>   Except
>   End;

Ловишь AV ? А ведь если "повезет" его может и не быть. И вообще отлов AV - идея ИМХО настолько плохая, что подобная техника никогда не должна быть использована.


 
GuAV ©   (2004-09-22 01:42) [6]

GuAV ©   (22.09.04 01:40) [5]

> Есть и другие способы достижения того чтобы указател укарывал
> на данные, например @ оператор.


> Первые две проверяют указатель на неравенство nil, но он
> может быть и не равен nil но и не указывать куда либо.

Кстати здесь же и объяснение [2]


 
Германн ©   (2004-09-22 02:28) [7]

Присоединяюсь к GuAV ©   (22.09.04 00:52) [2]
>В наиболее общем случае никак и незачем.
с одним лишь изменением (может быть, чисто синтаксическим).
Следовало бы ответить "В общем случае никак и незачем."

Это отвечая на сабж. Если нужно что-то большее, пожалуйста к нашим телепатам! Или сформируйте грамотнее свой вопрос.


 
Defunct ©   (2004-09-22 02:47) [8]

> Первые две проверяют указатель на неравенство nil, но он может быть и не равен nil но и не указывать куда либо.

Если указатель не равен Nil, то он уже по определению указывает на данные.

> например мусор в стеке или уже освобождённый объект/структура/др.

Ну и что? (выражаясь словами автора )  "была над указателем проведена процедура New()", а что уж потом с данными сделали не важно, главное, что факт New, или @, или присваивания, или GetMem мы установили.

> Ловишь AV ? А ведь если "повезет" его может и не быть.
Что значит повезет? Если P=Nil тут уж однозначно ответ ясен. Попутно еще и валидность данных отловится (если не Nil).

На вопрос
>>Вы что ни разу не пользовались хотя бы одной из этих конструкций
Вы так и не ответили.. Хотя я и не ждал, так как уверен, что вы использовали все перечисленные конструкции [4] в своих программах.


 
jack128 ©   (2004-09-22 02:51) [9]

Defunct ©   (22.09.04 2:47) [8]
Если указатель не равен Nil, то он уже по определению указывает на данные.

Угу, только вот на какие данные..

> Попутно еще и валидность данных отловится (если не
> Nil).

s := StringOfChar("A", 100);
p := @s[50];
s := StringOfChar("A", 20);
try
 ch := p^; // 100 к 1 - AV не будет..
except
end;


 
Defunct ©   (2004-09-22 03:04) [10]

jack128 ©   (22.09.04 02:51) [9]

> Угу, только вот на какие данные..
А кого это волнует, в вопросе не конкретизировалось, что надо проверить соответствие данных. Надо только проверить указывает указатель на что-либо. Да указывает.

> ch := p^; // 100 к 1 - AV не будет..
А с чего бы там быть AV? Все в порядке, прочитаем 50-й символ если {$R-} (тем более, что он там есть), иначе вылезет RangeCheck exception, я же не утверждал, что должен быть именно AV.


 
KSergey ©   (2004-09-22 08:05) [11]

> [10] Defunct ©   (22.09.04 03:04)
> jack128 ©   (22.09.04 02:51) [9]
>
> > Угу, только вот на какие данные..
> А кого это волнует, в вопросе не конкретизировалось, что
> надо проверить соответствие данных. Надо только проверить
> указывает указатель на что-либо. Да указывает.

В вопросе было про валидность данных, на которые указывает указатель.

> иначе вылезет RangeCheck

С какого такого перепугу??


 
Суслик ©   (2004-09-22 09:40) [12]

Вот Defunct образованный вроде парень, а такие советы дает иногда, просто эталон некорректного программирования. :))

Немного теории.

Манагер памяти дельфи устроен таким образом, что маленькие кусочки памяти (до 4кб если не ошибаюсь) при освобождении остаются как бы совственностью дельфи. И если после dispose туда что-то записть - огромная вероятность неполучения АV. Способ, предложенный, defunct c try except end очень ненадеждный. Если хочется проверить инициализирован ли указатель пусть один - строить логику работы программы так, чтобы в этом не возникало потребности.


 
Суслик ©   (2004-09-22 10:01) [13]

2defunct

> > Ловишь AV ? А ведь если "повезет" его может и не быть.
> Что значит повезет? Если P=Nil тут уж однозначно ответ ясен.
> Попутно еще и валидность данных отловится (если не Nil).

Я так понял, что выделенная фраза значит, что если P = nil, то точно будет AV?

Спешу заметить, что это не 100% гарантия. Все зависит от данных, с которыми работаешь: new можно делать не только для простых типов, но и для записей.

const
  cLen = 100000;
type
  pitem = ^titem;
  titem = record
     a: array[0..cLen] of longint;
  end;
var
  p: pitem;
begin
  p := nil;
  p^.a[cLen] := 10;
end;


Уверяю, что можно подобрать значение cLen таким, чтобы AV (p = nil!!!) не будет.


 
GuAV ©   (2004-09-22 14:30) [14]

Defunct ©   (22.09.04 02:47) [8]

> Ну и что? (выражаясь словами автора )  "была над указателем
> проведена процедура New()", а что уж потом с данными сделали
> не важно, главное, что факт New, или @, или присваивания,
> или GetMem мы установили.

инменно, автор спрашивал про New, и я ещё и о том, что NEW от GETMEM Ваши способы не отличат.

> Что значит повезет? Если P=Nil тут уж однозначно ответ ясен.
> Попутно еще и валидность данных отловится (если не Nil).

Суслик ©  уже ответил.
> Вы так и не ответили.. Хотя я и не ждал, так как уверен,
> что вы использовали все перечисленные конструкции [4] в
> своих программах.

Третью - использую когда уверен что P указывает на данные.
при этом в except либо (действие и raise) либо ловлю не все исключения.

Первое и вторая - одно и то же, кроме того, что вторая работает ещё и для методов. Соответсвенно использую обычно первую, а для методов вторую, но НЕ для проверки на [0]
> был ли над указателем проведена процедура New();


 
Anatoly Podgoretsky ©   (2004-09-22 14:41) [15]

Defunct ©   (22.09.04 02:47) [8]
Если указатель не равен Nil, то он уже по определению указывает на данные.
Если указатель равен Nil, то тоже указывает на данные, по адресу ноль. Просто это условность, соглашение, что мол адрес 0 считаем недействительным. Некто у нас уже пытался удалить переменную.


 
Amoeba ©   (2004-09-22 14:43) [16]

Интересно, куда пропал наш уважаемый автор вопроса?


 
Суслик ©   (2004-09-22 14:45) [17]

Рихтер пишет, что в win2000 32 пространство с $00000000 по $0000ffff используется для выясления недейтствительных указателей: любая поптыка чтения или записи в память по этим адресам вызывает нарушение доступа.

Рихтер
windows для профессионалов
изд 4
стр 316


 
Defunct ©   (2004-09-22 15:36) [18]

Доводы [15][17] - убедительные, согласен что в общем случае нельзя и незачем.

Но допустим, для случая когда в программе используется только NEW для выделения памяти под данные и данные не превышают 64k, тогда ответ [1] справедлив.


 
Суслик ©   (2004-09-22 15:39) [19]


>  [18] Defunct ©   (22.09.04 15:36)


> данные не превышают 64k, тогда ответ [1] справедлив.

мастак ты выкручиваться, как я посмотрю.

----------------
что такое "справедливость"? в мире цыфрЫ странное слово.
я, например, не берусь судить о справедливости.

хочешь пример, когда такой способ ужасен?
например, тебе нужно делать такую проверку 100000 раз в секунду (не спрашивай зачем, пример придумать легко)...
можешь попробовать, что у тебя получится (вернее не получится):))))


 
Defunct ©   (2004-09-22 15:59) [20]

> например, тебе нужно делать такую проверку 100000 раз в секунду (не спрашивай зачем, пример придумать легко)...

Да ладно, это уже извраты ;)

----------------
что такое "справедливость"? в мире цыфрЫ странное слово.
я, например, не берусь судить о справедливости.


Справедливость = True

PS: тока что посмотрел твою анкету, ты зачем себе сбрил усы? а я уже заволновался куда пропал старый добрый Тимохов. ;)


 
Суслик ©   (2004-09-22 16:06) [21]


>  [20] Defunct ©   (22.09.04 15:59)


> заволновался куда пропал старый добрый Тимохов. ;)

да это уже давно - редко ходишь

Я, конечно, перегнул немного про долгость try except. Но доля правды в этом есть. Да и вообще - не хорошо это. Надо писать правильно.


 
Anatoly Podgoretsky ©   (2004-09-22 16:24) [22]

Да не расчитывайте вы на except его срабатывание для данного случая зависит от расположения звезд на небе.
Правильнее подумать об нормальной организации программы, чтобы не надо было проверять или по крайней мере выделить одно из значений адресов для признака не выделенности, НИЛ для этого хорошо подходит.


 
GuAV ©   (2004-09-22 20:09) [23]


> Но допустим, для случая когда в программе используется только
> NEW для выделения памяти под данные и данные не превышают
> 64k, тогда ответ [1] справедлив.

Ну, если был New, а потом Dispose, то будет ли AV ?
Ответы "да" или "нет" не верны.
Здесь AV или будет или нет - не известно, возможна и "русская рулетка".

Аналогично, если в P "мусор".


> Правильнее подумать об нормальной организации программы

И это имхо самый правильный ответ на вопрос сабжа.


 
Palladin ©   (2004-09-22 20:30) [24]

New raise EOutOfMemory exception... остальное лежит на дисциплине кодирования...


 
Германн ©   (2004-09-23 01:58) [25]

Согласен с "Anatoly Podgoretsky ©   (22.09.04 16:24) [22] " в главном.
Но все таки Except - нужно учитывать!


 
Суслик ©   (2004-09-23 10:52) [26]


>  [25] Германн ©   (23.09.04 01:58)
>  [23] GuAV ©   (22.09.04 20:09)

Я тоже сказал, что нужно правильно программы писать, а не на except уповать.

------------------------------------------
Хочу заметить многоуважаемому Defunct"у, что это не первый раз, когда он  провоцирует обсуждение своих вредных советов. Это развлекалово такое? :)
На фик вредные советы давать...


 
Defunct ©   (2004-09-23 15:11) [27]

Суслик ©   (23.09.04 10:52) [26]

А чего не нравится "развлекалово"? мне такие споры приносят море удовольствия ;) Тем более, что хорошие вопросы здесь появляются доволно редко, а так есть повод поговорить на интересные темы.

> На фик вредные советы давать...
А они вредные? Автор споткнется раз, и если в голове не пусто то сам поймет как надо делать.

Я вообще-то любитель всего недокументированого и извращенных решений. Вот как вы считаете можно сделать синхронную передачу данных по линиям, совсем не предназначенным для передачи данных, например по линии  ACK LPT порта или по линиям CTS/RTS последовательного порта? Думаю 99% здесь присутствующих скажут - нельзя и незачем, а я скажу - можно и целесообразно, так как сам делал и оно работает (COM порт превращается в 3 COM порта).

PS: Кант в своем труде "Критика практического разума" приводит примеры абсолютно логичных доказателств, но совершенно противоположных по смыслу, одного и того же явления.


 
Германн ©   (2004-09-25 01:42) [28]

2 Defunct ©   (23.09.04 15:11) [27]

>Вот как вы считаете можно сделать синхронную передачу данных по линиям, совсем не предназначенным для передачи данных, например по линии  ACK LPT порта или по линиям CTS/RTS последовательного порта? Думаю 99% здесь присутствующих скажут - нельзя и незачем, а я скажу - можно и целесообразно, так как сам делал и оно работает (COM порт превращается в 3 COM порта).

Можно.
Многое можно! Но либо вернемся в ДОС, либо напишем драйверы, которые, скорее всего кроме автора, никому не нужны.

Прошу прощения за Offtopic!


 
Defunct ©   (2004-09-25 02:19) [29]

Германн ©   (25.09.04 01:42) [28]

Конечно, нетрудно сказать "можно" после того как уже был подтвержден факт рабочего решения.

> Многое можно! Но либо вернемся в ДОС, либо напишем драйверы, которые, скорее всего кроме автора, никому не нужны.

Что вы этой фразой хотели показать? Типа нестандартные решения - пустая трата времени и глупость? А знаете ли вы, что в телемеханике пракически все существующие решения - нестандартные, оттого и поставляется ПО с компьютерами впридачу, а не наоборот.

> Прошу прощения за Offtopic!
Same


 
GuAV ©   (2004-09-25 11:14) [30]

Вы Defunct таки действительно развели оффтопик, потому что каждое нестандартное решение требует своего обоснования, про COM порт у нас нет информации, может это и правильно, а по темам вроде этой> На фик вредные советы давать...


 
Defunct ©   (2004-09-25 12:02) [31]

GuAV ©   (25.09.04 11:14) [30]

см. [27]
>> На фик вредные советы давать...
>А они вредные? Автор споткнется раз, и если в голове не пусто то сам поймет как надо делать.

Вы считаете автору повредит знание:
P<>Nil
Assigned
и Try Except?

это недокументированные функции? или что-то запрещенное религией?
в чем проявляется вредность совета?
Может быть автору вопроса повредит дискуссия, которая здесь развернулась и всесторонне осветила его вопрос?
вам напомнить, что ваш совет был просто отрицательным.

> Вы Defunct таки действительно развели оффтопик
Разводят обычно 2 вещи - кроликов или личностей легко поддающихся убеждениям.
Я вел дискуссию не с вами, хочу обратить ваше внимание на то, что никого здесь не разводил, и вы не модератор, чтобы решать что  offtop, а что не offtop.


 
GuAV ©   (2004-09-25 14:27) [32]

GuAV ©   (25.09.04 11:14) [30]

>в чем проявляется вредность совета?

проитирую начало дискуссии:

][ncognito   (22.09.04 00:28)  
Ув. господа, подскажите, как узнать был ли над указателем проведена процедура New();

-----------------------------------------------------------------
Defunct ©   (22.09.04 00:33) [1]
Var P: Pointer = nil;

1. if P <> Nil Then <был создан, не обязательно New>

2. Try
   P^ := ....
 Except
   < не был создан >
 End;


Вредность совета в том, что Вы даёте неверные коментарии к Вашему коду.

> вам напомнить, что ваш совет был просто отрицательным.

он был правильным. если надо, могу продемострирорвать на примере что "никак". "незачем" не стоит писать программы чтоб это было нужно.


> вы не модератор, чтобы решать что  offtop, а что не offtop.

замечание принимается.


 
default ©   (2004-09-25 19:05) [33]

[2]
если сильно надо то можно подменять ф-ции делфийского менеджера памяти(операции с памятью само собой должны выполняться через них)внутри них записывать нужные данные по работе с памятью потом вызывать стандартный код
P.S. давно надо было в фак это закинуть
сколько можно на одно и тоже отвечать...


 
GuAV ©   (2004-09-25 20:09) [34]


> если сильно надо то можно подменять ф-ции делфийского менеджера
> памяти(операции с памятью само собой должны выполняться
> через них)внутри них записывать нужные данные по работе
> с памятью потом вызывать стандартный код

Допустим у нас массив из 100 указателей типа, который занимает 1 ГБ, мы вызываем для половины из них New. Естественно, память будет выделенна не для всех, т.к. на всех не хватит. Для каких мы вызвали New, неважно успешно или нет ? на это не отвечает даже подмена ф-ции делфийского менеджера памяти.


 
default ©   (2004-09-25 20:11) [35]

GuAV ©   (25.09.04 20:09) [34]
почему не отвечает - отвечает
надуманная проблема


 
default ©   (2004-09-25 20:13) [36]

GuAV ©   (25.09.04 20:09) [34]
почему не отвечает - отвечает
надуманная проблема
подобную инф-ию можно хранить если сильно хочется


 
GuAV ©   (2004-09-25 20:26) [37]


> подобную инф-ию можно хранить если сильно хочется

как?
в указателе нельзя - там либо объект либо nil.
хранить указатель на указатель?
хорошо, а если P1:=P2; ?

я всё ещё убеждён, что ответил правильно.


 
default ©   (2004-09-25 20:34) [38]

GuAV ©   (25.09.04 20:26) [37]
я имел ввиду хранить инф-у о том что память под указ-ль выделилась отдельно(не ввиде ненулевого значения этого указателя, а то это несерьёзно(конечно если прогр-т не следит на их значениями, как и нужно делать вообще, я ж не говорю что так НАДО делать так делать вообще-то не надо в больш-ве случае я лишь говорю что так МОЖНО делать и всё))
то есть хранить массив адресов по которым выдел-ась память
(т твоём примере нужно дополн-ую инф-ию хранить если нужно распо-ать указ-ли под которые была неудачная попытка выделить память)


 
GuAV ©   (2004-09-25 20:44) [39]


> (т твоём примере нужно дополн-ую инф-ию хранить если нужно
> распо-ать указ-ли под которые была неудачная попытка выделить
> память)

Угу, а как потом найти их учитывая что
P1:=P2; ?
ведь @P1<>@P2 ! т.е. как сопоставить инфу указателю ? никак.

и потом, New может делаться в первой либе из uses в initialization. А может он и в System/SysInit использован d initialization...


 
default ©   (2004-09-25 20:47) [40]

GuAV ©   (25.09.04 20:44) [39]
"и потом, New может делаться в первой либе из uses в initialization. А может он и в System/SysInit использован d initialization..."
да, но скорее всего автору нужно будет проверять корректность указателей память под которую он выделял
"Угу, а как потом найти их учитывая что
P1:=P2; ?
ведь @P1<>@P2 ! т.е. как сопоставить инфу указателю ? никак."
согласен, только не понял зачем это
ведь вроде как требовалось проверить значение указателя на актуальность(1)
вопрос автора был
"Ув. господа, подскажите, как узнать был ли над указателем проведена процедура New();"
и тут ты прав, но он скорее всего имел ввиду (1)



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2004.10.10;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.58 MB
Время: 0.037 c
1-1095758544
kand
2004-09-21 13:22
2004.10.10
Как "выдернуть" из DataTimePicker или MonthCalendar номер месяца?


3-1095062673
Mitrofan
2004-09-13 12:04
2004.10.10
EhLib DBGrid


3-1094652066
Mefodiy
2004-09-08 18:01
2004.10.10
Ошибка "Invalid file name" при SQL запросе


14-1095645323
Думкин
2004-09-20 05:55
2004.10.10
С днем рождения! 20 сентября


3-1094815391
Koala
2004-09-10 15:23
2004.10.10
Помогите разобраться





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский