LINUX.ORG.RU

Непонятки со смартами

 ,


0

1

Привет. Досталась небольшая игруля в наследство, здесь есть куча код вида

SomeObject* obj = new SomeObject();
obj->init();
obj-setBla();
obj-setBla();
obj-setBla();

this->addChild(obj, param1, param2);
obj->release();
Чтобы не париться, я сделал типо так
boost::shared_ptr<SomeObject>obj(new SomeObject());
obj->init();
obj-setBla();
obj-setBla();
obj-setBla();

this->addChild(obj.get(), param1, param2);
Но когда меняю на смарт, то сразу после запуска все очень громко падает. Собственно вопрос, где я туплю. Спсб.

пилять.

ну зачем ты shared-ptr бездумно воткнул?

даже не посмотрев описание что делает get(), и что он не делает. что происходит после удаления shared-ptr.

ckotinko ☆☆☆
()
Ответ на: комментарий от anonymous

да он банально удаляет объект, оставив висящую ссылку, полученную через get().

ckotinko ☆☆☆
()
Ответ на: комментарий от anonymous

нет, там все объекты наследуются от базового класса, который в себе содержит счетчик ссылок, на подобие как сделано в обж-с с retain-release

Boy_from_Jungle ★★★★
() автор топика
Ответ на: комментарий от ckotinko

даже не посмотрев описание что делает get()

pointer get() const;
Returns the pointer pointing to the owned object

Boy_from_Jungle ★★★★
() автор топика
Ответ на: комментарий от Boy_from_Jungle

Значит, addChild ретейнит объект (что очень логично). А shared_ptr вызывает не release, а delete. Можно переписать на release.

note173 ★★★★★
()

очевидно obj->release(); не тоже самое, что delete obj, ну и shared_ptr уже в стандарте, нет смысла использовать бустовскую реализацию

wota ★★
()
Ответ на: комментарий от Boy_from_Jungle

тогда может внутри addChild увеличивается счетчик m_uReference

anonymous
()
  • Откройте konqueror
  • Введите в адресную строчку gg:boost::intrusive_ptr
  • Тыркните стрелку справа в конце адресной строчки
quiet_readonly ★★★★
()

Было 7 строчек работающего читабельного кода, стало 6 неработающего нечитабельного, но он не парится.:)

anonymous
()
Ответ на: комментарий от buddhist

Это типа такой костыльный gc для C++ что ли?

Умные указатели и сборка мусора - это всё-таки несколько разные вещи.

Deleted
()
Ответ на: комментарий от Deleted

Умные указатели и сборка мусора - это всё-таки несколько разные вещи

Это не мешает многим личностям использовать первое в качестве второго.

encyrtid ★★★★★
()
Ответ на: комментарий от encyrtid

gc не нужен.

да нет, нужен конечно, как бы еще можно было бы писать портянки вроде:


using System;
using System.ComponentModel;

// The following example demonstrates how to create
// a resource class that implements the IDisposable interface
// and the IDisposable.Dispose method.

public class DisposeExample
{
    // A base class that implements IDisposable.
    // By implementing IDisposable, you are announcing that
    // instances of this type allocate scarce resources.
    public class MyResource: IDisposable
    {
        // Pointer to an external unmanaged resource.
        private IntPtr handle;
        // Other managed resource this class uses.
        private Component component = new Component();
        // Track whether Dispose has been called.
        private bool disposed = false;

        // The class constructor.
        public MyResource(IntPtr handle)
        {
            this.handle = handle;
        }

        // Implement IDisposable.
        // Do not make this method virtual.
        // A derived class should not be able to override this method.
        public void Dispose()
        {
            Dispose(true);
            // This object will be cleaned up by the Dispose method.
            // Therefore, you should call GC.SupressFinalize to
            // take this object off the finalization queue
            // and prevent finalization code for this object
            // from executing a second time.
            GC.SuppressFinalize(this);
        }

        // Dispose(bool disposing) executes in two distinct scenarios.
        // If disposing equals true, the method has been called directly
        // or indirectly by a user's code. Managed and unmanaged resources
        // can be disposed.
        // If disposing equals false, the method has been called by the
        // runtime from inside the finalizer and you should not reference
        // other objects. Only unmanaged resources can be disposed.
        protected virtual void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if(!this.disposed)
            {
                // If disposing equals true, dispose all managed
                // and unmanaged resources.
                if(disposing)
                {
                    // Dispose managed resources.
                    component.Dispose();
                }

                // Call the appropriate methods to clean up
                // unmanaged resources here.
                // If disposing is false,
                // only the following code is executed.
                CloseHandle(handle);
                handle = IntPtr.Zero;

                // Note disposing has been done.
                disposed = true;

            }
        }

        // Use interop to call the method necessary
        // to clean up the unmanaged resource.
        [System.Runtime.InteropServices.DllImport("Kernel32")]
        private extern static Boolean CloseHandle(IntPtr handle);

        // Use C# destructor syntax for finalization code.
        // This destructor will run only if the Dispose method
        // does not get called.
        // It gives your base class the opportunity to finalize.
        // Do not provide destructors in types derived from this class.
        ~MyResource()
        {
            // Do not re-create Dispose clean-up code here.
            // Calling Dispose(false) is optimal in terms of
            // readability and maintainability.
            Dispose(false);
        }
    }
    public static void Main()
    {
        // Insert code here to create
        // and use the MyResource object.
    }
}

вместо обычного деструктора

wota ★★
()
Ответ на: комментарий от wota

ну и конечно вызывать это дело тоже очень просто и удобно:

using(MyResource myRes = new MyResource(handle))
{
    myRes.DoSomething();
}

куда там плюсам:

MyResource(handle).DoSomething();
wota ★★
()
Ответ на: комментарий от quiet_readonly

Спасибо, я за него и забыд вообще, т.к. раньше не использовал.
Единственное почему-то работает только как шаблонные ф-ции. Ладно потом разберемся.

Boy_from_Jungle ★★★★
() автор топика
Ответ на: комментарий от buddhist

умные указатели это не ручное управление памятью

Reset ★★★★★
()
Ответ на: комментарий от anonymous

просто не тот смарт взял, т.к. провтыкал посмотреть что делал метод, вот и все.

Boy_from_Jungle ★★★★
() автор топика
Ответ на: комментарий от buddhist

в ручном управлении памяти нет ничего плохого, если знать что делаешь. Смарты иногда хорошо помогают.

Boy_from_Jungle ★★★★
() автор топика
Ответ на: комментарий от wota

Как понимаю, ты стянул пример из MSDN, где показано как удалять из управляемого кода неуправляемый ресурс (обратить внимание на приставку «не-»). Что ты хотел этим показать?

dave ★★★★★
()
Ответ на: комментарий от wota

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

Что тут сложного?

MyResource(handle).DoSomething();

Что будет если в DoSomething вылетит exception?

encyrtid ★★★★★
()
Ответ на: комментарий от dave

показано как удалять из управляемого кода неуправляемый ресурс

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

wota ★★
()
Ответ на: комментарий от encyrtid

Что будет если в DoSomething вылетит exception?

сработает деструктор, как и положено

wota ★★
()
Ответ на: комментарий от dave

и да - это конструкция очень популярна в C# и Java, только в другом виде - try/finally + ручное дергание метода для освобождения ресурсов, но этого было мало и в этих ЯП родили еще костыли, вроде приведеного выше

wota ★★
()
Ответ на: комментарий от wota

что объект удаляется по фазам луны

Учи IDisposable. В реальном коде используют using для удаления ресурсов.

dave ★★★★★
()
Ответ на: комментарий от wota

и да - это конструкция очень популярна в C# и Java, только в другом виде - try/finally + ручное дергание метода для освобождения ресурсов, но этого было мало и в этих ЯП родили еще костыли, вроде приведеного выше

Это и есть try/finally, конструкция:

using(var file = new FileStream(@"filename", FileMode.Open))
{
    //... code
}
разворачивается в:
FileStream file = new FileStream(@"filename", FileMode.Open);
try
{
    //... code
}
finally
{
    if(file != null)
       ((IDisposable)file).Dispose();
}
Это гарантирует освобождение неуправляемых ресурсов сразу по выходу из using-блока.

encyrtid ★★★★★
()
Ответ на: комментарий от encyrtid

Это и есть try/finally

спасибо кэп, будешь вторым К.О. после dave

wota ★★
()
Ответ на: комментарий от wota

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

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

encyrtid ★★★★★
()
Ответ на: комментарий от encyrtid

Неуправляемые ресурсы освобождаются сразу

конечно сразу, конечно, вот как вручную метод дернут - так сразу и освободятся, а если не дернут, или забудут костыль вокруг поставить - ну и хрен с ним, пусть висит

wota ★★
()
Ответ на: комментарий от wota

конечно сразу, конечно, вот как вручную метод дернут - так сразу и освободятся, а если не дернут, или забудут костыль вокруг поставить - ну и хрен с ним, пусть висит

Ты из цирка сбежал что-ли? Легче забыть реализовать закрытие дескриптора в деструкторе, чем не обернуть неуправляемый объект в using.

encyrtid ★★★★★
()
Ответ на: комментарий от dave

С ним нет смысла дальше дискутировать.

конечно нет, фанаты GC уверено слили - вместо ручного управления памятью они получили ручное управление ресурсами + длинный и костыльный код, но пыжаться изо всех сил

wota ★★
()
Ответ на: комментарий от encyrtid

Легче забыть реализовать закрытие дескриптора в деструкторе, чем не обернуть неуправляемый объект в using.

у вас очень плохая память

wota ★★
()
Ответ на: комментарий от wota

хотя нужно сказать, что GC может быть удобным - например в D

wota ★★
()
Ответ на: комментарий от wota

конечно нет, фанаты GC уверено слили - вместо ручного управления памятью они получили ручное управление ресурсами + длинный и костыльный код, но пыжаться изо всех сил

Реализуй, например, персистентное дерево на смартпойнтерах и посмотри на производительность сего поделия. А потом посмотрим кто слил.

encyrtid ★★★★★
()
Ответ на: комментарий от wota

Тогда отсылаю тебя читать книгу «Стандарты программирования на C++» в той части, где говорится об уровнях безопасности при работе с исключениями (по-моему так называется тема, книги нет сейчас под рукой, а заглядывал в нее последний раз очень давно за ненадобностью). «Фанаты GC» могут спать спокойно уже потому, что самый первый примитивный уровень безопасности обеспечивается у них автоматически. Нефанаты же должны его обеспечивать самостоятельно в Cи++.

Ты правда думаешь, что с ресурсами проще работать в Си++?

dave ★★★★★
()
Ответ на: комментарий от dave

Тогда отсылаю тебя читать книгу «Стандарты программирования на C++» в той части, где говорится об уровнях безопасности при работе с исключениями

поверь - я в курсе, и знаю про грабли

Ты правда думаешь, что с ресурсами проще работать в Си++?

я б сказал лаконичнее, т.к. стек + RAII

П.С, убегаю, сегодня уже не буду

wota ★★
()
Ответ на: комментарий от Boy_from_Jungle

в общем, раз у тебя уже есть __встроенный__ счетчик ссылок, то используй его через intrusive_ptr.

shared_ptr создает __отдельный__ счетчик ссылок, поэтому он срать хотел на то, кто еще использует твой класс через встроенный счетчик.

ckotinko ☆☆☆
()
Ответ на: комментарий от encyrtid

Реализуй, например, персистентное дерево на смартпойнтерах и посмотри на производительность сего поделия. А потом посмотрим кто слил.

Twitter went from 60 second of Garbage Collection (GC) per hour to 5 seconds per 3.5 days, mainly because of the internal slab allocator.

школьники такие школьники

ckotinko ☆☆☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.