Почему остается лишняя память?

86
15 июля 2021, 03:50

Есть код:

#include <iostream>
using namespace std;
#define TOTAL_SIZE 1024 * 1024
typedef struct Point
{
    double x;
    double y;
} point_t;
typedef struct Allocator
{
    void dealloc()
    {
        for (size_t i = 0; i < size; i++)
        {
            free(block[i]);
            block[i] = nullptr;
        }
        size = 0;
    }
    void* block[TOTAL_SIZE];
    size_t size = 0;
} alloc;
alloc al;
point_t* createPoint(double x, double y)
{
    point_t* point = (point_t*)malloc(sizeof(point_t));
    point->x = x;
    point->y = y;
    al.block[al.size] = point;
    al.size++;
    return point;
}
point_t* ppp[TOTAL_SIZE];
int main()
{
    for (size_t i = 0; i < TOTAL_SIZE; i++)
    {
        ppp[i] = createPoint(i, i);
    }
    al.dealloc();
    system("pause");
    return 0;
}

Чтобы отслеживать память, в visual studio можно воспользоваться так называемой Process Memory(ниже есть фото). Я решил заглянуть в него, и увидел, что в самом начале выполнения программы у меня 10,2MB выделено памяти, а в конце 11,1MB, я не понимаю откуда эта разница.

И также почему здесь эта яма?(фото из Process Memory)

Answer 1

Process Memory показывает память, запрошенную процессом у ОС. Никто вам не обещал, что освобождение ваших объектов point_t приведет к возврату всей выделенной памяти обратно в ОС. Теоретически библиотека времени выполнения C/C++ может вообще не возвращать память в ОС, т.е. вы вы можете вообще не увидеть никакого падения графика Process Memory при освобождении памяти через free. В вашем случае видно, что какая-то память была возвращена, а какая-то - нет. Любые локальные "впадины", "выпуклости" и прочие особенности формы вашего графика - это не более чем внутренние особенности некоего эвристического алгоритма в библиотеке времени выполнения C/C++, который принимает решение о том, когда и какую память вернуть в ОС.

Попробуйте в своем эксперименте внутри функции dealloc освобождать не все выделенные point_t, а через один. И вы увидите, что несмотря на то, что половина выделенной памяти была освобождена, Process Memory не уменьшился вообще. Ибо возврата памяти в ОС в таком варианте не происходит.

P.S. В современных реализациях Visual Studio локальный менеджмент динамической памяти реализуется уже большей частью в Windows API, а библиотека времени выполнения является лишь тонкой оболочкой над ним, но суть от этого не меняется.

READ ALSO
Как работает подключение connect?

Как работает подключение connect?

Как устроена функция connect? Как лучше реализовать, стоит ли подключать 2 или 10 соединений с разными серверамиЧто будет, если подключений больше...

91
GNU GCC compiler CodeBlocks не компелируется

GNU GCC compiler CodeBlocks не компелируется

Поставил CodeBlocks для плюсов, компилятор GNU GCCНе запускается, пишет следующее:

108
Как Нарисовать полукруги вокруг центра с помощью Qt?

Как Нарисовать полукруги вокруг центра с помощью Qt?

Необходимо нарисовать полукруги вокруг центра с помощью Qt

75
Как правильно использовать enable_shared_from_this?

Как правильно использовать enable_shared_from_this?

Я пытаюсь понять, зачем вообще нужно использовать enable_shared_from_this?

67