Re[32]: delete this
От: Аноним  
Дата: 11.04.07 13:20
Оценка:
У меня есть два модуля. Один получает указатель на интерфейс путем вызова функции другого (в котором делается new/delete или чтото еще).
Какое право имеет первый модуль звать delete на указатель который он получил не при помощи new? Откуда он знает что указатель ТАМ был создан при помощи new? (даже если положить на специфичные проблемы совместимости с рантаймами). Если объект был получен вызовом экспортной функции дллки — GetObject то вообще правильнее всего будет сделать экспортную функцию ReleaseObject для освобождения. "Но зачем две экспортируемые функции если можно сделать Release у самого объекта?" подумали MS когда делали COM и оставили только DllGetClassObject .
Re[18]: delete this
От: minorlogic Украина  
Дата: 11.04.07 13:44
Оценка: 1 (1) +1
Я дополню рассуждения.

Как в первом методе компилятор может узнать сколько памяти ему удалить ? А как вообще он узнает что память надо удалять , если оператор delete перегружен у потомка ?

Т.е. фактически первый вариант нежизнеспособен.
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[18]: delete this
От: minorlogic Украина  
Дата: 11.04.07 13:45
Оценка:
Я дополню рассуждения.

Как в первом методе компилятор может узнать сколько памяти ему удалить ? А как вообще он узнает что память надо удалять , если оператор delete перегружен у потомка ?

Т.е. фактически первый вариант нежизнеспособен.
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[33]: delete this
От: night beast СССР  
Дата: 11.04.07 15:40
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Ну тоже мне проблема. Если известно что модуль test* возвращаемый ехешником — массив то реализация Release внутри выполнит корректное удаление массива. Вопрос правда — а что толку с массива объектов если мы не знаем его длину?


ну, если не проблема, покажи как переписать код на Release.
Re[33]: delete this
От: night beast СССР  
Дата: 11.04.07 15:45
Оценка:
Здравствуйте, Аноним, Вы писали:

А>У меня есть два модуля. Один получает указатель на интерфейс путем вызова функции другого (в котором делается new/delete или чтото еще).

А>Какое право имеет первый модуль звать delete на указатель который он получил не при помощи new? Откуда он знает что указатель ТАМ был создан при помощи new? (даже если положить на специфичные проблемы совместимости с рантаймами).

все вопросы справедливы и для самого объекта. откуда он знает что его создали с помошью new?
Re[34]: delete this
От: Аноним  
Дата: 14.04.07 11:11
Оценка:
NB>все вопросы справедливы и для самого объекта. откуда он знает что его создали с помошью new?
Модуль — абстрация более высокого уровня чем объект, потому объект может в принципе и знать.
Re[35]: delete this
От: night beast СССР  
Дата: 14.04.07 11:24
Оценка:
Здравствуйте, Аноним, Вы писали:

NB>>все вопросы справедливы и для самого объекта. откуда он знает что его создали с помошью new?

А>Модуль — абстрация более высокого уровня чем объект, потому объект может в принципе и знать.

раз уж вспомнил про абстракции, скажи, нужно ли объекту вообще что нибудь знать про распределение памяти?
Re[36]: delete this
От: Аноним  
Дата: 14.04.07 13:50
Оценка:
NB>раз уж вспомнил про абстракции, скажи, нужно ли объекту вообще что нибудь знать про распределение памяти?
Самому объекту — необязательно, но он может отнаследоваться от объекта который знает, и в котором реализован соответствующий Release
Re[37]: delete this
От: night beast СССР  
Дата: 14.04.07 14:01
Оценка:
Здравствуйте, Аноним, Вы писали:

NB>>раз уж вспомнил про абстракции, скажи, нужно ли объекту вообще что нибудь знать про распределение памяти?

А>Самому объекту — необязательно, но он может отнаследоваться от объекта который знает, и в котором реализован соответствующий Release

если ты хочешь поддерживать различные стратегии вделения/освобождения, то тебе придется передаать эту информацию в объект.
Re[38]: delete this
От: Аноним  
Дата: 14.04.07 14:41
Оценка: 4 (2)
NB>если ты хочешь поддерживать различные стратегии вделения/освобождения, то тебе придется передаать эту информацию в объект.
Дану?

//Interface.h:
class IExportedObject
{
public:
    virtual void Release() = 0;
};

class IBusinessLogicObject : public IExportedObject
{
public:
    virtual void Foo() = 0;
};


//BusinessLogic.*:
class MyObject : public IBusinessLogicObject 
{
public:
    virtual ~MyObject()
    {
        printf("~MyObject\n");
    }
    virtual void Foo()
    {
        printf("Foo\n");
    }
};

//ExportIntafaces.*:
template <class T>
class ExportSingle : public T
{
public:
    virtual ~ExportSingle()
    {
        printf("~ExportSingle\n");
    }

    virtual void Release()
    {
        delete this;
    }
};

template <class T>
class ExportArray : public T
{
public:
    virtual ~ExportArray()
    {
        printf("~ExportSingle\n");
    }
    virtual void Release()
    {
        delete[] this;
    }
};


extern __declspec(dllexport) IBusinessLogicObject *CreateObject()
{
    return new ExportSingle<MyObject>;
}

extern __declspec(dllexport) IBusinessLogicObject *CreateObjects(int n)
{
    return new ExportArray<MyObject>[n];
}


//application
int main(int argc, char * argv[])
{
    IBusinessLogicObject *object = CreateObject();
    object->Release();
    
    IBusinessLogicObject *objects = CreateObjects(10);
    objects->Release();
    
    return 0;
}
Re[39]: delete this
От: night beast СССР  
Дата: 14.04.07 16:56
Оценка:
Здравствуйте, Аноним, Вы писали:

NB>>если ты хочешь поддерживать различные стратегии вделения/освобождения, то тебе придется передаать эту информацию в объект.

А>Дану?

+1

о таком не подумал.
однако по прежнему не совсем видны преимущества по сравнению с враппером с кустомным делетером.
Re[40]: delete this
От: Аноним  
Дата: 15.04.07 12:31
Оценка:
NB>о таком не подумал.
NB>однако по прежнему не совсем видны преимущества по сравнению с враппером с кустомным делетером.
А это и есть враппер с кастомным делетером. Только более языко-платформно-независимый чем возврат boost::shared_ptr'а.
Re[41]: delete this
От: Аноним  
Дата: 15.04.07 12:36
Оценка: 1 (1) +1
А>А это и есть враппер с кастомным делетером. Только более языко-платформно-независимый чем возврат boost::shared_ptr'а.
Поясню. Что должен сделать программист на делфи или .Net чтобы использовать длл, возвращающую boost::shared_ptr?
Re[42]: delete this
От: night beast СССР  
Дата: 15.04.07 14:24
Оценка: :)
Здравствуйте, Аноним, Вы писали:

А>>А это и есть враппер с кастомным делетером. Только более языко-платформно-независимый чем возврат boost::shared_ptr'а.

А>Поясню. Что должен сделать программист на делфи или .Net чтобы использовать длл, возвращающую boost::shared_ptr?

опыта работы с .нет нету, поэтому ничего не скажу.
Re[18]: delete this
От: Erop Россия  
Дата: 04.09.07 08:36
Оценка:
M>
M>static void* operator new (size_t s)
M>{
M>    printf("new from native module\n");
M>    return malloc(s);
M>}

M>static void operator delete (void* p)
M>{
M>    printf("delete from native module\n");
M>    return free(p);
M>}
M>


Это противоречит стандарту! operator new/delete должны быть либо методами классов/стркутур, либо функциями в глобальном пространстве имён с внешней линковкой!!!

M>Еще раз повторяю , что используется для удаления менежер памяти , именно то который и создавал. А после эксперимента , уберите виртуальный деструктор.

Ну всё хорошо, только надо у example ещё operator new/delete перекрыть!!!

Например, так:
struct CSafeDeletableBase {
    virtual ~CSafeDeletable() {}
    
    void* operator new( size_t size ) { return ::operator new( size ); }
    void operator delete( void* block ) { ::operator delete( block ); }

    // Дальнейшие шаблоны по желниаю....
    template<typename T1>
        void* operator new( size_t size, T1 a1 ) 
            { return ::operator new( size, a1 ); }
    template<typename T1>
        void operator delete( void* block, T1 a1 ) 
            { return ::operator delete( block, a1 ); }
         
    template<typename T1, typename T2>
        void* operator new( size_t size, T1 a1, T2 a2 ) 
            { return ::operator new( size, a1, a2 ); }
    template<typename T1, typename T2>
        void operator delete( void* block, T1 a1, T2 a2 ) 
            { return ::operator delete( block, a1, a2 ); }
         
    // и т. д.
};

Ну и потом выводить из CSafeDeletableBase всё, что может удаляться из разных модулей...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: delete this
От: Erop Россия  
Дата: 04.09.07 08:41
Оценка:
Здравствуйте, gid_vvp, Вы писали:

BP>>Объекты создаются динамически (new) фабрикой, фабрика в одной dll, созданные объекты используются в другой. "delete obj" вызывать из другой dll я по понятным причинам не могу, поэтому решил так делать.


_>В этом случае лучше чтоб фабрика возвращала умный указатель, который бы сам всё подчищал


При таком подходе можно нечаянно всё только запутать
Умный указатель обычно шаблон, соответсвенно где именно реализуются и куда линкуются методы шаблона вопрос философский (оч. зависит от того, что где кому и как. Палтформы там, компилятора, опций...) Соответсвенно из какой dll возмётся operator delete никто не знает ((
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[20]: delete this
От: Erop Россия  
Дата: 04.09.07 09:02
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>Вы поставили довольно четкую проблему (а именно удаление памяти соответствующим менеджером памяти). Я написал как ее решить, С++ СОВМЕСТИМО. Написал тест демонстрирующий мои тезисы. Запустите его на той платформе где хотите совместимости.


Твоё решение несовместимо, увы.

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

Нет. Это всё по стандарту.

Смотри.
Вызоав правильного мэнеджера гарантирует нифига не виртуальный деструктор, а operator new/delete определённые у класса.
А виртуальный деструктор призван решать другую проблему -- вызывать нужный деструктор из иерархии. При этом может возникнуть неприятная ситуация, когда у разных членов иерархии используются разные мэнеджеры памяти. Стандарт эту тему нынче разрудивает (это случилось вовсе и не сразу, кстати, но таких старых компилятором найти трудно). Так что если у класса есть виртуальный деструктор и есть перекрытый operator delete, то компилятор обязан позвать нужный operator delete. Так как ни DLL ни разных глобальных operator delete в стандарте нет, то и никакой спецификации на этот случай нет. И авторы компиляторов могут делать так, как им нравится. Например, им может нравится inline opearator delete, что обречёт их избегать, по возможности, виртуальности при его вызове...

Но, тем не мнее, в твоей идее, ИМХО, есть здравое зерно. Типа раз уж мы вводим виртуальный деструктор, то стоит и operator new/delete перекрыть. Типа ПРИГОДДИТСЯ (с) изв. анекдот
Ну а чтобы не так муторно было перекрывать, надо написать один раз базу
Автор: Erop
Дата: 04.09.07
, где всё перекрыто и объявлено, а потом из неё выводиться
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[22]: delete this
От: Erop Россия  
Дата: 04.09.07 09:06
Оценка:
Здравствуйте, Sergey, Вы писали:

А>>Если такое решение требует отдельного изучения реализации таблицы виртуальных методов в каждом из компиляторов — извольте. Мне нужен С++ решение.


S>Их нет. В стандарте ничего не говорится про dll, статическую-динамическую линковку рантайма и т.д.


зато говорится всё-таки о менеджерах памяти в виде операторов new и delete.
смотри тут
Автор: Erop
Дата: 04.09.07
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[15]: delete this
От: Erop Россия  
Дата: 04.09.07 09:15
Оценка:
Здравствуйте, BoberPlus, Вы писали:

BP>Если линковка с рантаймом статическая (по умолчанию это так), то каждый dll будет иметь свой менеджер памяти, поэтому нельзя делать "delete obj", если obj был создан в другом модуле.


Только если ты не перекрыл и экспортировал operator new/delete для своего кроссDLLьного объекта
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.