C++Builder - глюки с auto_ptr...
От: Vladik Россия  
Дата: 31.07.02 12:42
Оценка:
Привет!

Вот такой вот код глючит при разрушении TSomeObject (не вызывается деструктор TSomeControl)

class TSomeControl : public TGraphicControl
...

class TSomeObject : public TDragObject
{
std::auto_ptr<TSomeControl> SomeControl;
...
};
...
__fastcall TSomeObject::~TSomeObject()
{
//    SomeControl.reset(NULL);
}


Если раскомментарить строчку — все работает как надо. Кто-нибудь может прокомментировать?
Как все запущенно...
Re: C++Builder - глюки с auto_ptr...
От: temofey  
Дата: 31.07.02 15:55
Оценка:
Здравствуйте Vladik, Вы писали:

V>Привет!

V> Кто-нибудь может прокомментировать?
Попрбую...
Ты используешь метод связи кучи со стеком.
Сдесь выделеная в куче память освобождается автоматически при освобождении стека.
Дело в том, что строгий указатель(strong pointer), который Ты используешь, состоит из шаблона std::auto_ptr<>
а данный шаблон в своем деструкторе освобождает память, которую Ты выделил в куче.
Насколько Я понимаю, вся прелесть использования auto_ptr<> и состоит в том, чтобы ручками потом не удалять
твой объект, ты его создал...и забыл.
Re[2]: C++Builder - глюки с auto_ptr...
От: Vladik Россия  
Дата: 31.07.02 19:30
Оценка:
Здравствуйте temofey, Вы писали:

T>Насколько Я понимаю, вся прелесть использования auto_ptr<> и состоит в том, чтобы ручками потом не удалять

T>твой объект, ты его создал...и забыл.

Дык. Почему оно глючит, в случа автоматического удаления? Почему не вызывается деструктор? Я прошелся дебагером — деструктор для самого auto_ptr вызывается, и в нем как и положено делается delete the_p; Но вот для привязанного к нему объекта просто освобождается память, без вызова деструктора этого объекта.
Как все запущенно...
Re[3]: C++Builder - глюки с auto_ptr...
От: Anatolix Россия https://www.linkedin.com/in/anatolix/
Дата: 01.08.02 11:05
Оценка:
Здравствуйте Vladik, Вы писали:

V>Дык. Почему оно глючит, в случа автоматического удаления? Почему не вызывается деструктор? Я прошелся дебагером — деструктор для самого auto_ptr вызывается, и в нем как и положено делается delete the_p; Но вот для привязанного к нему объекта просто освобождается память, без вызова деструктора этого объекта.


Могу поспорить что ты забыл деструктор сделать виртуальным у объекта
Любая проблема дизайна может быть решена введением дополнительного абстрактного слоя, за исключением проблемы слишком большого количества дополнительных абстрактных слоев
Re[4]: C++Builder - глюки с auto_ptr...
От: Vladik Россия  
Дата: 01.08.02 11:37
Оценка:
Здравствуйте Anatolix, Вы писали:

A>Могу поспорить что ты забыл деструктор сделать виртуальным у объекта


Объект, как было указано, является наследником TGraphicControl, т.е. имеет виртуальный деструктор по определению. Кроме того, он явно описан виртуальным
Нет, это здесь непрчем, иначе auto_ptr.reset() тоже бы не работало.
Как все запущенно...
Re[5]: C++Builder - глюки с auto_ptr...
От: Anatolix Россия https://www.linkedin.com/in/anatolix/
Дата: 01.08.02 11:42
Оценка:
Здравствуйте Vladik, Вы писали:

V>Здравствуйте Anatolix, Вы писали:


A>>Могу поспорить что ты забыл деструктор сделать виртуальным у объекта


V>Объект, как было указано, является наследником TGraphicControl, т.е. имеет виртуальный деструктор по определению. Кроме того, он явно описан виртуальным

V>Нет, это здесь непрчем, иначе auto_ptr.reset() тоже бы не работало.

Ты знаешь такого не бывает. Проверь на всякий случай
в деструкторе auto_ptr при delete ptr. ptr равен нулю или нет?

Т.е. здесь вообще у тебя проблемы похоже не auto_ptr а просто
с удалением(обыкновенное удаление работает если у тебя не
auto_ptr?)

Корме того если ты используешь dll то могут быть проблемы в распределении
памяти из-за неправильно сборки. см вот это
http://www.softforum.ru/cbuilder.faq/faq.asp?24

Кстати а что тебе CodeGuard на эту тему говорит?
Любая проблема дизайна может быть решена введением дополнительного абстрактного слоя, за исключением проблемы слишком большого количества дополнительных абстрактных слоев
Re[6]: C++Builder - глюки с auto_ptr...
От: Vladik Россия  
Дата: 01.08.02 11:59
Оценка:
Здравствуйте Anatolix, Вы писали:

A>Ты знаешь такого не бывает. Проверь на всякий случай

A>в деструкторе auto_ptr при delete ptr. ptr равен нулю или нет?

Я же уже писал — прошелся дебагером. В обоих случаях в конце-концов приходим к строке delete the_p; с валидным the_p. Только в одном случае этот delete делается из деструктора auto_ptr, в другом — из метода reset. В одном случае вызывается деструктор моего объекта, в другом — СС3250MT.operator delete(void *), который вызывает _free и больше ничего не делает.

A>Т.е. здесь вообще у тебя проблемы похоже не auto_ptr а просто

A>с удалением(обыкновенное удаление работает если у тебя не
A>auto_ptr?)

Блин, а что же тогда по-твоему auto_ptr.reset(NULL), если не явное удаление???

A>Корме того если ты используешь dll то могут быть проблемы в распределении

A>памяти из-за неправильно сборки.

У меня обычный exe. Динамические/статические RTL/пакаджи никак не влияют на результат.

см вот это
A>http://www.softforum.ru/cbuilder.faq/faq.asp?24
A>Кстати а что тебе CodeGuard на эту тему говорит?

Ничего не говорит. На редкость глюкавая вещь и я его не юзаю, берегу нервы.
Как все запущенно...
Re[7]: C++Builder - глюки с auto_ptr...
От: temofey  
Дата: 01.08.02 14:00
Оценка:
Здравствуйте Vladik, Вы писали:


A>>Кстати а что тебе CodeGuard на эту тему говорит?

V>Ничего не говорит. На редкость глюкавая вещь и я его не юзаю, берегу нервы.

Зря, утечки в памяти ловит лихо!
Сердцевина шаблона авто_птр:

auto_ptr<X>::auto_ptr(X*p)
{
the_p=p;
}
//---
auto_ptr<X>::~auto_ptr()
{
delete the_p;
}
//---
X*auto_ptr<X>::operator->()
{
return the_p;
}
//---
X&auto_ptr<X>::operator*()
{
return *the_p;
}

Написано так:
Строгий указатель владеет памятью или объектом, на который он указывает. Важно понимать,
что созданный объект не может существовать дольше строгого указателя.
В твоем случае строгий указатель и память, на которую он указывает должны быть удалены
автоматически в конце области действия. Конечно, его можно использовать, даже если память имеет меньшую
продолжительность жизни, чем область действия. В этом случае нужно просто сообщить строгому
указателю об освобождении памяти с помощью reset();
Вообщето класс авто_птр был признан протеворечивым и включен в стандарт в самый последный момент.
Память у тебя освобождается? Так? значит авто_птр работает нормально.
Деструктор объекта не вызывается?
хер его знает почему...
Все сказал.
Re[8]: C++Builder - глюки с auto_ptr...
От: Vladik Россия  
Дата: 01.08.02 15:15
Оценка:
Здравствуйте temofey, Вы писали:

V>>Ничего не говорит. На редкость глюкавая вещь и я его не юзаю, берегу нервы.

T>Зря, утечки в памяти ловит лихо!

Я же говорю — пользоваться им нереально. Совершенно нелепые глюки в самых разных позах. Начиная с ошибок линковки и кончая ругательствами не по делу. В небольших проектиках — как правило проблем не возникает.

T>Вообщето класс авто_птр был признан протеворечивым и включен в стандарт в самый последный момент.


В каком месте он противоречивый? А с учетом того, что в VCL и шага не ступишь без new — это супер актуальная вещь. Вот чего я не понимаю, почему в стандарте наряду с auto_ptr нету смартпоинтера с подсчетом ссылок. Приходится свой велосипед изобретать.

T>Память у тебя освобождается? Так? значит авто_птр работает нормально.

T>Деструктор объекта не вызывается?
T>хер его знает почему...

А у меня и нет никаких претензий к auto_ptr... Но вот такие "заскоки" компилятора мне совершенно не нравятся.
Как все запущенно...
Re[9]: C++Builder - глюки с auto_ptr...
От: temofey  
Дата: 01.08.02 15:33
Оценка:
Здравствуйте Vladik, Вы писали:

T>>Вообщето класс авто_птр был признан протеворечивым и включен в стандарт в самый последный момент.


V>В каком месте он противоречивый?


Пишется так:
Класс авто_птр содержит метод гет(), который следует использовать с чрезвычайной осторожностью, так как он возвращает прямую ссылку на область памяти, которой владеет указатель. Только один строгий указатель может владеть выделенной в куче памятью. А данный метод позволяет создать другой строгий указатель, который указывает на эту память и владеет ею. Он также может использоваься для высвобождения памятм, которой владее строгий указатель.
Вероятно именно по этой причине класс авто_птр был признан протеворечивым и включен в стандарт только в последний момент. Как видно, этого нельзя избежать, поскольку должен существовать способ передачи неформатированного уеазателя вывам апи функций, в которых он используется. При использовании метода гет() убедитесь в том, что он вызывается только для тех фунеций, которые не освобождат эту облать памяти. Если все же функция освобождает выделенную область памяти, то программисту придется позаботиться от том, чтобы вызвать метод релеасе() еще до использования строгого указателя или до выхода из области действия и попытки снова освободить эту память.
А на тему смарт-поинтера...дык, так он у меня есть
встретил его когда-то на прилагаемом к книге компакт — диске...ВОТ
Все сказал.
Re[10]: C++Builder - глюки с auto_ptr...
От: Vladik Россия  
Дата: 02.08.02 06:25
Оценка:
Здравствуйте temofey, Вы писали:

V>>В каком месте он противоречивый?

T>Пишется так:
T>Класс авто_птр содержит метод гет(), который следует использовать с чрезвычайной осторожностью, так как он возвращает прямую ссылку на область памяти, которой владеет указатель.

Блин, ну надо же... Прямую ссылку на память, это просто ужасно
Але!!! Это все-таки C++, а не VB

Противоречивым я бы назвал:

auto_ptr<T>::operator T *(){return get();}


т.е. неявное приведение к указателю, а также

auto_ptr<T> &auto_ptr<T>::operator = (T *p){reset (p); return *this;}


т.е. неявное приравнивание новому указателю. Но таких методов у auto_ptr и нет, хотя в некоторых ситуациях они были бы очень даже востребованы (например при работе с некоторыми STL-ими алгоритмами). Эти методы действительно можно назвать "опасными" и это правильно, что их нет.
А при использовании get()/reset() явно видно, что происходит и это не опасней работы с любым другим классом C++.

T>А на тему смарт-поинтера...дык, так он у меня есть


Он у всех есть. Вопрос в том, почему его нет в стандарте?
Как все запущенно...
Re: C++Builder - глюки с auto_ptr...
От: Vladik Россия  
Дата: 17.08.02 17:14
Оценка:
Привет!

Блин, опять тоже самое но уже в другом месте. Что за !@#$??? Неужели никто не сталкивался???
Пробовал "локализовать" багу на новом пустом проекте — не получается. Но зато частично "локализовал" в существующем проекте на простом классе-заглушке. Глюк проявляется, если на момент объявления auto_ptr<X> класс X полностью не объявлен, т.е. есть только ссылка на него ( class X; ) Причем, как я уже говорил, проявляется бага только в определенных местах (юнитах) проекта.
Как все запущенно...
Re[2]: C++Builder - глюки с auto_ptr...
От: Андрей Тарасевич Беларусь  
Дата: 17.08.02 17:49
Оценка: 12 (1)
Здравствуйте Vladik, Вы писали:

V>Привет!


V>Блин, опять тоже самое но уже в другом месте. Что за !@#$??? Неужели никто не сталкивался???

V>Пробовал "локализовать" багу на новом пустом проекте — не получается. Но зато частично "локализовал" в существующем проекте на простом классе-заглушке. Глюк проявляется, если на момент объявления auto_ptr<X> класс X полностью не объявлен, т.е. есть только ссылка на него ( class X; ) Причем, как я уже говорил, проявляется бага только в определенных местах (юнитах) проекта.

Ну так это классическая проблема. Класс X должне быть полностью объявлен к моменту инстанциирования 'auto_ptr<X>'. Иначе будут глюки. Происходит именно то неопределенное поведение, о котором предупреждает пункт 5.3.5/5 станарта языка.
Best regards,
Андрей Тарасевич
Re[3]: C++Builder - глюки с auto_ptr...
От: Андрей Тарасевич Беларусь  
Дата: 17.08.02 17:55
Оценка:
Здравствуйте Андрей Тарасевич, Вы писали:

V>>Блин, опять тоже самое но уже в другом месте. Что за !@#$??? Неужели никто не сталкивался???

V>>Пробовал "локализовать" багу на новом пустом проекте — не получается. Но зато частично "локализовал" в существующем проекте на простом классе-заглушке. Глюк проявляется, если на момент объявления auto_ptr<X> класс X полностью не объявлен, т.е. есть только ссылка на него ( class X; ) Причем, как я уже говорил, проявляется бага только в определенных местах (юнитах) проекта.

АТ>Ну так это классическая проблема. Класс X должне быть полностью объявлен к моменту инстанциирования 'auto_ptr<X>'. Иначе будут глюки. Происходит именно то неопределенное поведение, о котором предупреждает пункт 5.3.5/5 станарта языка.


Вот такой код воспроизведет проблему без 'auto_ptr'

[ccode]
struct X;

void foo(X* p)
{
delete p;
}

struct X
{
~X() { printf("Destructor\n"); }
};

void bar(X* p)
{
delete p;
}

int main()
{
foo(new X);
bar(new X);
}
[/cсode]

В первом случае деструктор не будет вызван. Во втором — будет. Но в такой ситуации компиляторы обычно выдают предупреждение, а вот с 'auto_ptr' — не всегда умеют.
Best regards,
Андрей Тарасевич
Re[3]: C++Builder - глюки с auto_ptr...
От: Vladik Россия  
Дата: 17.08.02 18:18
Оценка:
Здравствуйте Андрей Тарасевич, Вы писали:

АТ>Ну так это классическая проблема. Класс X должне быть полностью объявлен к моменту инстанциирования 'auto_ptr<X>'. Иначе будут глюки. Происходит именно то неопределенное поведение, о котором предупреждает пункт 5.3.5/5 станарта языка.


Прочитал, прочувствовал. И я в непонятках
Это ж каким местом они там в Комитете думали, чтобы такое принять??? Почему просто не ругаться на delete obj; для неопределенного класса???
Как все запущенно...
Re[4]: C++Builder - глюки с auto_ptr...
От: Vladik Россия  
Дата: 17.08.02 18:51
Оценка:
Здравствуйте Андрей Тарасевич, Вы писали:

АТ>В первом случае деструктор не будет вызван. Во втором — будет. Но в такой ситуации компиляторы обычно выдают предупреждение, а вот с 'auto_ptr' — не всегда умеют.


Все, локализовал! А вот выдать warning не удалось заставить. Может какая опция хитрая есть? (VC6.0 выдает варнинг уже при -W2).
Как все запущенно...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.