Re[4]: delete this
От: Аноним  
Дата: 08.04.07 19:41
Оценка: :)
_>В этом случае лучше чтоб фабрика возвращала умный указатель, который бы сам всё подчищал
А кто будет удалять сам умный указатель?
void Release(){delete this;} — нормальная практика.
Re[15]: delete this
От: minorlogic Украина  
Дата: 08.04.07 19:47
Оценка: -1
Лучше бы ты тесты сделал.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[15]: delete this
От: dotidot Россия  
Дата: 08.04.07 19:53
Оценка:
Здравствуйте, BoberPlus, Вы писали:

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

да какая разница, может — не может. сиравно будет плохо.
Re[15]: delete this
От: NikeByNike Россия  
Дата: 08.04.07 19:54
Оценка:
Здравствуйте, BoberPlus, Вы писали:

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


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


А что мешает мультитред сделать?
Нужно разобрать угил.
Re[16]: delete this
От: BoberPlus  
Дата: 08.04.07 19:58
Оценка: :)
Здравствуйте, minorlogic, Вы писали:

M>Лучше бы ты тесты сделал.

Ну что я на это кроме такого же хамства ответить могу ?
Re[16]: delete this
От: BoberPlus  
Дата: 08.04.07 20:00
Оценка:
Здравствуйте, NikeByNike, Вы писали:

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


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


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


NBN>А что мешает мультитред сделать?


чаво чаво ?
Re[16]: delete this
От: Аноним  
Дата: 08.04.07 20:31
Оценка:
M>Лучше бы ты тесты сделал.
Да ты што? Ну вот сделал тест:
Dll:
class BaseObj
{
public:
    __stdcall BaseObj(){};
    virtual __stdcall ~BaseObj()
    {
    }
    virtual void __stdcall Release()
    {
        delete this;
    }
};

extern "C" __declspec(dllexport) BaseObj *__stdcall obj_new()
{
    return new BaseObj;
}

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                     )
{
    return TRUE;
}


Exe:
#include <stdio.h>
#include <conio.h>
#include <windows.h>

class BaseObj
{
public:
    __stdcall BaseObj(){};
    virtual __stdcall ~BaseObj()
    {
    }
    virtual void __stdcall Release()
    {
        delete this;
    }
};

extern "C" __declspec(dllimport) BaseObj *__stdcall obj_new();

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                     )
{
    return TRUE;
}


int main(int argc, char* argv[])
{
    typedef BaseObj *(__stdcall *tobj_new)();
    tobj_new pobj_new = (tobj_new)::GetProcAddress(::LoadLibrary(TEXT("testmemdll.dll")), "_obj_new@0");

    if (!pobj_new)
    {
        printf("dll or function not found\n");
        getch();
        return -1;
    }

    printf("Press '1' to use delete or '2' to use Release\n");
    switch (getch())
    {
    case '1':
        {
            for(;;)
            {
                BaseObj *obj = pobj_new();
                delete obj;
                delete new char[256];
            }
        }
        break;
    case '2':
        {
            for(;;)
            {
                BaseObj *obj = pobj_new();
                obj->Release();
                delete new char[256];
            }
        }
        break;
    }

    return 0;
}

Скомпилял 6й студией со статическим рантаймом.. Запустил — работает 1 и 2... (нихера себе подумали суровые сибирские мужики)
Скомпилял exe шник борландовским дебилдером. Запустил 2 — работает, 1 — вылетает (агааа подумали суровые сибирские мужики)

Так вот — устойчивая работа на тестах лишь необходимое условие нормальной работы кода, тк тестами все не покроешь. Достаточное условие — соответствие документации. А документация ясно говорит:
If you choose to link with the static runtime library, then your module has its own private copy of the C/C++ runtime. When your module calls new or malloc, the memory can only be freed by your module calling delete or free. If another module calls delete or free, that will use the C/C++ runtime of that other module which is not the same as yours. Indeed, even if you choose to link with the DLL version of the C/C++ runtime library, you still have to agree which version of the C/C++ runtime to use. If your DLL uses MSVCRT20.DLL to allocate memory, then anybody who wants to free that memory must also use MSVCRT20.DLL.
(c) http://blogs.msdn.com/oldnewthing/archive/2006/09/15/755966.aspx — блог одного из главных разработчиков винды.
Re[16]: delete this
От: Аноним  
Дата: 08.04.07 20:37
Оценка:
NBN>А что мешает мультитред сделать?
Хотя бы то что стабильная работа кода в таком случае — лишь побочное следствие implementation details конкретного менеджера памяти, которая может изменится в будущем. Либо потом в будущем в вашем проекте захотят использовать другой аллокатор (например stlport с его SGI node-optimized allocator), а тут — опачки. Да и каким нить мемори трекером типа devpartner'а такой код отлаживать будет просто невозможно.
Re[17]: delete this
От: NikeByNike Россия  
Дата: 08.04.07 20:44
Оценка:
Здравствуйте, BoberPlus, Вы писали:

NBN>>А что мешает мультитред сделать?


BP>чаво чаво ?


Multi-threaded DLL
Нужно разобрать угил.
Re[17]: delete this
От: NikeByNike Россия  
Дата: 08.04.07 20:48
Оценка:
Здравствуйте, Аноним, Вы писали:

NBN>>А что мешает мультитред сделать?

А>Хотя бы то что стабильная работа кода в таком случае — лишь побочное следствие implementation details конкретного менеджера памяти, которая может изменится в будущем.
Согласен, зависит от степени универсальности... Но в принципе, мне его хватало всегда, за исключением разработки миддлеваре.

А>Либо потом в будущем в вашем проекте захотят использовать другой аллокатор (например stlport с его SGI node-optimized allocator), а тут — опачки.

А это то тут при чем??? По моему ты спутал мухи и котлеты...

А>Да и каким нить мемори трекером типа devpartner'а такой код отлаживать будет просто невозможно.

Мне всегда хватало собственных средств. Они всеравно необходимы если используешь что-нибудь типа smallallocator на подобии Александресовского.
Нужно разобрать угил.
Re[18]: delete this
От: Аноним  
Дата: 08.04.07 20:56
Оценка:
А>>Либо потом в будущем в вашем проекте захотят использовать другой аллокатор (например stlport с его SGI node-optimized allocator), а тут — опачки.
NBN>А это то тут при чем??? По моему ты спутал мухи и котлеты...
При том что при подключении STLPORT с дефолтовыми настройками new/delete вызывают не аллокатор CRT, а внутренний аллокатор STLPORT'а.
ЗЫ задолбали цитировать тупой прикол с мухами и котлетами.
Re[19]: delete this
От: NikeByNike Россия  
Дата: 08.04.07 20:59
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>>Либо потом в будущем в вашем проекте захотят использовать другой аллокатор (например stlport с его SGI node-optimized allocator), а тут — опачки.

NBN>>А это то тут при чем??? По моему ты спутал мухи и котлеты...
А>При том что при подключении STLPORT с дефолтовыми настройками new/delete вызывают не аллокатор CRT, а внутренний аллокатор STLPORT'а.

Пускай вызывает. Это же совершенно разные вещи. Если аллокатор STLPORT'а не позволяет работать с контейнерами между dll — то это бага конкретно STLPORT, а не стандартного аллокатора.
Нужно разобрать угил.
Re[20]: delete this
От: Аноним  
Дата: 08.04.07 21:08
Оценка:
NBN>Пускай вызывает. Это же совершенно разные вещи. Если аллокатор STLPORT'а не позволяет работать с контейнерами между dll — то это бага конкретно STLPORT, а не стандартного аллокатора.
Вы не поняли. То что станартный МТ аллокатор позволяет выделять/освобождать память между длл это не его фича, а негарантируемая документацией деталь реализации. Соответственно если сторонний аллокатор эту деталь каким либо образом делает неюзабельной — никакой не баг, а просто специфика конкретное реализации, а баг — всегда в коде которые не соответствует документации. То бишь — в вашем.
Re[21]: delete this
От: NikeByNike Россия  
Дата: 08.04.07 21:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Вы не поняли. То что станартный МТ аллокатор позволяет выделять/освобождать память между длл это не его фича, а негарантируемая документацией деталь реализации. Соответственно если сторонний аллокатор эту деталь каким либо образом делает неюзабельной — никакой не баг, а просто специфика конкретное реализации

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

А>а баг — всегда в коде которые не соответствует документации. То бишь — в вашем.

Знаешь чем отличаются баги от фич?
Нужно разобрать угил.
Re[18]: delete this
От: BoberPlus  
Дата: 09.04.07 05:34
Оценка:
Здравствуйте, NikeByNike, Вы писали:

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


NBN>>>А что мешает мультитред сделать?


BP>>чаво чаво ?


NBN>Multi-threaded DLL


Судьда, но не красиво , плюс ряд проблем связанных с динамической линковкой рантайма.
Re[22]: delete this
От: Аноним  
Дата: 09.04.07 06:29
Оценка:
А>>а баг — всегда в коде которые не соответствует документации. То бишь — в вашем.
NBN>Знаешь чем отличаются баги от фич?
Баг — поведение кода, противоречащее документации.
Re[3]: delete this
От: Sm0ke Россия ksi
Дата: 09.04.07 06:49
Оценка:
Здравствуйте, BoberPlus, Вы писали:

BP>>>Простой вопрос — допустима ли такая конструкция ?


BP>>>
BP>>>void Obj::release()
BP>>>{
BP>>>   delete this;
BP>>>}
BP>>>


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


Освобождать память надо (желательно) в том-же модуле, где она выделялась.
Если new находится в cpp файле фабрики, а методы Obj::release() разбросаны по всему проекту, то это не очень хорошо.

либо:
Перегрузите операторы new/delete в базовом классе (задефайнить в одном cpp), остальные создаваемые фабрикой классы наследуйте от него.
либо:
Поместите методы release() всех объектов в тот-же cpp, где они создаются (где фабричный метод).
Re[19]: delete this
От: Аноним  
Дата: 09.04.07 07:12
Оценка:
BP>Судьда, но не красиво , плюс ряд проблем связанных с динамической линковкой рантайма.
Одна из них — разные динамические рантаймы у разных модулей
например msvcrt.dll vs msvcr80.dll
Re[5]: delete this
От: gid_vvp  
Дата: 09.04.07 07:23
Оценка:
ПК>К сожалению, "умных" указателей нужно более одной разновидности, и дублировать их для каждого объекта не всегда удобно.
Это как?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: delete this
От: Павел Кузнецов  
Дата: 09.04.07 12:06
Оценка:
Здравствуйте, gid_vvp, Вы писали:

ПК>>К сожалению, "умных" указателей нужно более одной разновидности, и дублировать их для каждого объекта не всегда удобно.


_>Это как?


Для возвращаемого значения или других случаев, где нужно подчеркнуть передачу владения -- auto_ptr, для объекта, который никуда из данной области видимости "уплыть не должен" -- scoped_ptr, для объекта с разделяемым владением -- shared_ptr, для не владеющих ссылок на него -- weak_ptr и т.п. Если объект нельзя удалять "обычным" delete, жизнь в этом контексте становится сложнее.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.