Помогите определить утечку памяти - PullRequest
1 голос
/ 04 июля 2010

У меня есть класс, который определен так:

struct USERFPOINT
{
    POINTFLOAT UserPoint;
    POINTFLOAT LeftHandle;
    POINTFLOAT RightHandle;
    bool isBezier;
};

struct SHAPEOUTLINE {
    GLuint OutlineVBO;
    int OutlineSize;
    int OutlineWidth;
    ARGBCOLORF OutlineColor;
};

struct SHAPECONTOUR{

    std::vector<USERFPOINT> UserPoints;
    std::vector<std::vector<GLdouble>> DrawingPoints;
    SHAPEOUTLINE Outline;

};
struct SHAPEGRADIENT{
    GLuint TextureId;
    bool IsParent;
    bool active;
    int type;
    std::vector<ARGBCOLORF> colors;
};

struct SHAPEDIMENSIONS {
    POINTFLOAT Dimensions;
    POINTFLOAT minima;
    POINTFLOAT maxima;
};

class OGLSHAPE
{
private:
    int WindingRule;
    GLuint TextureCoordsVBOInt;
    GLuint ObjectVBOInt;
    UINT ObjectVBOCount;
    UINT TextureCoordsVBOCount;
    SHAPEGRADIENT Gradient;
    SHAPEDIMENSIONS Dimensions;
    void SetCubicBezier(USERFPOINT &a,USERFPOINT &b, int &currentcontour);

    void GenerateLinePoly(const std::vector<std::vector<GLdouble> > &input, int width);
public:
    std::string Name;
    ARGBCOLORF MainShapeColor;
    std::vector<SHAPECONTOUR> Contour;
    OGLSHAPE(void);

    void UpdateShape();
    void SetMainColor(float r, float g, float b, float a);
    void SetOutlineColor( float r, float g, float b, float a,int contour );
    void SetWindingRule(int rule);
    void Render();
    void Init();
    void DeInit();
    ~OGLSHAPE(void);
};

Вот что я сделал в качестве теста. Я создал глобальный std::vector<OGLSHAPE> тест.

В функции, которую я использовал, я создал

OGLSHAPE т.

Затем я отправил 50000 копий t в тест.

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

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

Затем я сделал то же самое, но перед тем, как вставить t в тест, я нажал SHAPECONTOUR (который я только что создал без изменения или добавления чего-либо в контур), прежде чем вставить t в тест.

На этот раз после очистки теста было выделено еще 3 мегабайта. Я сделал это снова, выделив вдвое больше, и теперь 6МБ у нас осталось. Использование памяти программой достигло 150 МБ и уменьшилось до 12 МБ, но должно быть 8,5 МБ. Поэтому это должно быть классифицировано как утечка памяти, хотя я не вижу, как. Я не вижу ничего, что могло бы сделать это. SHAPECONTOUR - это просто структура векторов с вложенной структурой векторов.

Почему это может привести к утечке, и как я могу это исправить?

Спасибо

Ответы [ 6 ]

2 голосов
/ 04 июля 2010

Если вы удалили все, утечки по определению нет. Я не вижу развернутых указателей, поэтому все удаляется. Следовательно, у вас нет утечек.

Вероятно, ОС просто решила оставить эту память доступной для вашей программы по любой причине. (Он не «восстановил» его.) Или, может быть, ему нужно выделить группы по 4 МБ, поэтому переход с 12 МБ на 8 МБ не оставит достаточной памяти. Или ...

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

1 голос
/ 04 июля 2010

Когда вы выделяете большие порции памяти, ЭЛТ сохраняет часть ее на время, когда вам нужно распределить снова.Вы не можете использовать диспетчер задач для указания утечек.

Если в вашем классе используются самоочищающиеся элементы, такие как vector, они не пропускают память.

0 голосов
/ 18 ноября 2011

Какие инструменты отладки вы использовали? Попробуйте еще один делакер! это просто!

0 голосов
/ 04 июля 2010

Как вы очищаете эти векторы?Попробуйте использовать в деструкторах что-то вроде этого:

std::vector<SHAPECONTOUR>().swap(Contour);

И сделайте то же самое с другими векторами из вашего кода (UserPoints, DrawingPoints, цвета).

0 голосов
/ 04 июля 2010

Как насчет явной очистки векторов SHAPECONTOUR в деструкторе OGLSHAPE?Повторите тест с этим и проверьте, если у вас все еще наблюдается утечка.

0 голосов
/ 04 июля 2010

Я бы предложил использовать инструмент обнаружения утечек, чтобы выяснить, есть ли у вас утечка. Например, для Windows dev вы можете использовать Visual Leak Detector (VLD) .

Если у вас действительно есть утечка, то, вероятно, она не там, где вы думаете.

Также вы можете ошибаться, потому что утечки вообще нет. Например, если вы просматриваете статистику только через диспетчер задач, это не означает, что в вашей программе есть утечка. ОС, которая запускает вашу программу, является отдельным зверем, отличным от языка программирования, внутри которого вы можете иметь утечку. То есть ОС может занять больше времени, чтобы восстановить освобожденную память.

Edit:

Если вы хотите убедиться, что vector имеет capacity 0, довольно часто нужно сделать следующее:

v.swap(std::vector<char>());
assert(v.capacity() == 0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...