Notes_New et Delete_operator new et l'opérateur delete_memory pool

Nouveau et Supprimer

Nouvelle différence sans parenthèses

1> Il n'y a aucune différence s'il y a une classe vide.
2> Il y a des variables membres, et celles avec des parenthèses effaceront une partie de la mémoire liée aux variables membres, pas la mémoire de l'objet entier est nulle 3>
Lorsqu'il y a un constructeur, les deux méthodes d'écriture sont cohérentes et la mémoire ne sera pas effacé. C'est au constructeur.

class Test3d
{
public:
    Test3d()
    {
        cout << "Init" << endl;
    }
    ~Test3d()
    {
        cout << "Delete" << endl;
    }
};
int main()
{
    Test3d* ptr = new Test3d;
    Test3d* ptr2 = new Test3d;
    delete ptr;
    delete ptr2;
    ptr = nullptr;
    ptr2 = nullptr;
    return 0;
}

Le processus en cours d'exécution de Nouveau et Supprimer

nouveau


Appelé Operate new 
Appelé Malloc Mémoire allouée
Appelé le constructeur de classe (le cas échéant)


supprimer


Appelé le destructeur de la classe,
appelé opera delete
, appelé Free pour libérer de la mémoire

La récupération de la mémoire de suppression a un large éventail d'influence

class Test3d
{
public:
    void fun()
    {
        char* pp = new char[10];
        memset(pp, 0, 10);
        delete[] pp;
    }
};


Les octets récupérés sont supérieurs à 10 octets et il peut y avoir plus
de mémoire allouée que 10 octets. En mode débogage, les informations de débogage occupent 30 à 60 octets, le nombre d'enregistrements alloués, 4 octets, etc.

opérateur nouveau 和 opérateur supprimer

//自己实现new和delete
class Test3d
{
public:
    static void* operator new(size_t size);
    static void operator delete(void *phead);
};
void* Test3d::operator new(size_t size)
{
    Test3d* ppoint = (Test3d*)malloc(size);
    return ppoint;
}
void Test3d::operator delete(void* phead)
{
    free(phead);
}

void func()
{
    Test3d* pa = new Test3d();
    delete pa;
}
int main()
{
    func();
    return 0;
}


Le constructeur et le destructeur ici sont toujours gérés par le compilateur.
 Si vous ne voulez pas utiliser votre propre
Test3d* pa = ::new Test3d();
    ::delete pa;

ajoutez un double-virgule avant d'appeler la nouvelle suppression du système

opérateur nouveau【】 和 opérateur supprimer【】

La construction et la destruction sont appelées 3 fois, mais les opérateurs new et delete ne sont appelés qu'une seule fois

class Test3d
{
public:
    static void* operator new[](size_t size);
    static void operator delete[](void *phead);
};
void* Test3d::operator new[](size_t size)
{
    Test3d* ppoint = (Test3d*)malloc(size);
    return ppoint;
}
void Test3d::operator delete[](void* phead)
{
    free(phead);
}

void func()
{
    Test3d* ptr = new Test3d[3];
    delete[] ptr;
}
int main()
{
    func();
    return 0;
}

pool de mémoire

Fonction et principe


Fonction : réduire le nombre d'appels de malloc et réduire le gaspillage de mémoire.
Principe : tout d'abord, malloc s'applique à un gros bloc de mémoire, et allouez-le un peu. Si ce n'est pas suffisant, alors malloc un gros bloc de mémoire

L'implémentation de code de pool de mémoire la plus simple

class Test3d
{
public:
    static void* operator new(size_t size);
    static void operator delete(void *phead);
    static int m_iCount;//分配计数统计,new一次统计一次
    static int m_iMallocCount; //分配计数统计,Malloc一次统计一次
private:
    Test3d* next;
    static Test3d* m_FreePos;//内存首地址
    static int m_sTrunkCount;//分配多少倍的内存
};
int Test3d::m_iCount = 0;
int Test3d::m_iMallocCount = 0;
Test3d* Test3d::m_FreePos = nullptr;
int Test3d::m_sTrunkCount = 5;


void* Test3d::operator new(size_t size)
{
    Test3d* tempLink;//需要返回的一个内存块
    if (m_FreePos == nullptr)
    {
        size_t tempSize = m_sTrunkCount * size;
        m_FreePos = reinterpret_cast<Test3d*>(new char[tempSize]);
        tempLink = m_FreePos;
        for (; tempLink!=&m_FreePos[m_sTrunkCount-1]; tempLink++)
        {
            tempLink->next = tempLink + 1;
        }
        tempLink->next = nullptr;
        ++m_iMallocCount;
    }
    ++m_iCount;
    tempLink = m_FreePos;
    m_FreePos = m_FreePos->next;
    return tempLink;
}
void Test3d::operator delete(void* phead)
{
    (static_cast<Test3d*>(phead))->next = nullptr;
    m_FreePos = static_cast<Test3d*>(phead);
}

void func()
{
    clock_t start, end;
    start = clock();
    for (int i = 0;i<500'0000;i++)
    {
        Test3d* ptr = new Test3d();
    }
    end = clock();
    cout << "申请分配内存的次数为:" << Test3d::m_iCount << endl;
    cout << "实际malloc的次数为:" << Test3d::m_iMallocCount << endl;
    cout << "用时为:" << end - start << "毫秒" << endl;
}
int main()
{
    func();
    return 0;
}

Remarque : Cette version est la version la plus simple et vous pouvez observer les performances de temps d'optimisation spécifiques du pool de mémoire.

Guess you like

Origin blog.csdn.net/qq_35337794/article/details/121773117