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

1.

Тщательный контроль нужен за своими собственными объектами созданными с помощью new которые к IrrLicht отношения не имеют, простенький пример:

struct tile { int texIdx; };

std::vector< std::vector<tile *> >tiles;
tiles.resize(1);
tiles[1] = new tile;

ирлихту глубоко пофигу до вашего tiles и tile в нем если вы сами не сделаете delete tiles[ 1], прежде чем сделать вновь tiles[1] = new tile, то произойдет утечка памяти на величину равную sizeof(tile)

P.s. ну это наверное и ежу понятно

2.

Если вы создали с помощью new объект IrrLicht’а к примеру так:

new irr::scene::SMesh cube_mesh = new irr::scene::SMesh;

и отдали на контроль ирлихту

smgr->addMeshSceneNode(cube_mesh);

то после передачи, если не хотите контролировать объект, надо выполнить cube_mesh->drop();
ни в коем случае delete - получите критическое завершение программы после delete cube_mesh;

если не выполнить drop будет утечка памяти,  объекты в ирлихте самоудаляются если счетчик ссылок на них равен нулю. Счетчик ссылок на ваш объект будет равен двум, вы первый раз увеличили счетчик создав объект  с помощью new (referenceCount=1) и второй раз увеличили счетчик отдавая объект ирлихту addMeshSceneNode (referenceCount=2). Когда при необходимости ирлихт будет удалять ненужные объекты, то будет уменьшать число ссылок с помощью remove(), но вызывать этот метод он будет один раз для каждого объекта, а не два, поэтому ваш объект останется жив.

Правда, это не касается случая когда вы хотели бы чтобы после авточистки ваши «личные» объекты остались нетронутыми, в этом случае drop выполнять не надо, но все же когда будете применять к объекту delete убедитесь что getReferenceCount() возвращает единицу иначе, если приложение должно продолжить работу рискуете получить критический вылет.

3.

если вы хотите избавиться от объекта который вы «попросили» у ирлихта, к примеру вот так

IMeshSceneNode *msn = smgr-> addCubeSceneNode();

удалять такой объект можно только

msn->remove();

воспользовавшись drop() или delete рискуете получить критический вылет из приложения.

Ну вот и все, успехов всем

кстати smgr – это объект irr::scene::ISceneManager


Отзывов: 6 на “IrrLicht: три правила против утечки памяти и возможный критических ошибок”

  1. Barega ()

    1) Насчет векторов.
    Смысла использовать new с std::vector – не имеет.

    Если делаем с использованием new – переписываем деструктор, в котором все это дело и удаляем. Но это – излишество.

    2) Опять же – на кой использовать new? В игростроении смысл имеет если ты менеджер памяти свой создал, иначе толку от него…
    Если уж нравится new, пользуй синглтон и удаляй при выходе из приложения.

    3) То же самое…
    По сути IrrLicht плохо написан сам, так что… там из-за такого вылеты и возможны.

  2. Эльмиго ()

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

    2) я менеджеров не создавал, я создаю динамически 3д модели

    3) иногда объекты теряют необходимость на этапе выполнения, нет смысла их хранить до конца выполнения программы

    P.s. у меня есть 3 правила, а вылеты кончились
    скажи лучше как лучше сделать клон объекта, если у него нет собственного метода для этого?

  3. Adobe ()

    хороший отчет, достаточно интересный анализ и понятные итоги
    спасибо за инфу

  4. OEM ()

    Познавательно, буду иметь ввиду!

  5. Digan ()

    В одной очень умной книжке прочитал, что грамотнее всего освобождать память вот так.

    if (pointer != NULL)
    {
    memset(pointer, GARBAGE_DATA, MemoryBlockSize(pointer));
    delete pointer;
    pointer = NULL;
    }

    Как там написано: «Один из лучших способов обрушить программу -вызвать функциии delete() или free() для указателя, который уже освобожден»

  6. uHTF ()

    Дельные мысли, возьму на заметку.


Оставьте свой отзыв

Вы должны войти, чтобы оставлять комментарии.