Оператор размера delete [] никогда не вызывается - PullRequest
3 голосов
/ 30 апреля 2019

Я пытаюсь отследить, сколько памяти было выделено в моих разработках.Распределение легко отслеживать, поскольку перегрузки void *operator new (size_t) и void *operator new[](size_t) позволяют отслеживать, сколько выделено.С C ++ можно прибегнуть к технике перераспределения памяти для хранения размера выделения

Начиная с C ++ 14, есть соответствующие void operator delete(void*p, size_t size)и void operator delete[](void*p, size_t size), который должен позволять точно учитывать каждый перераспределение (за исключением удаления неполного типа, которое затем оставляется для реализации).

Однако, хотя первая версия вызываетсяg ++, где сделан вызов для удаления одного объекта, я не нашел ни одного компилятора, вызывающего второй.Вот мой тестовый код:

#include <iostream>
size_t currentAlloc;

void * operator new(size_t size)
{
    currentAlloc += size;
    std::cout << "1\n";
    return malloc(size);
}

void *operator new[](size_t size)
{
    std::cout << "3\n";
    currentAlloc += size;
    return malloc(size);
}

void operator delete(void *p) noexcept
{
    std::cout << "Unsized delete\n";
    free(p);
}

void operator delete(void*p, size_t size) noexcept
{
    std::cout << "Sized delete " << size << '\n';
    currentAlloc -= size;
    free(p);
}

void operator delete[](void *p) noexcept
{
    std::cout << "Unsized array delete\n";
    free(p);
}

void operator delete[](void*p, std::size_t size) noexcept
{
    std::cout << "Sized array delete " << size << '\n';
    currentAlloc -= size;
    free(p);
}

int main() {
    int *n1 = new int();
    delete n1;

    int *n2 = new int[10];
    delete[] n2;

    std::cout << "Still allocated: " << currentAlloc << std::endl;
}

Скомпилировано с g++ -std=c++14 test.C или clang++ -std=c++14 test.C.Результат, который выводит для g ++:

1
Удаление размера 4
3
Удаление массива без размера
Выделено еще: 40

Я ожидал, что удаление размера массива будет вызвано для второго delete, а последнее напечатанное значение будет 0 вместо 40. clang ++ не вызывает перераспределение любого размера и компилятор Intel.

Мой код неверен?Я неправильно понимаю стандарт?Или g ++ и clang ++ не соответствуют стандарту?

1 Ответ

3 голосов
/ 30 апреля 2019

Согласно cppreference.com , который обычно является надежным, неизвестно, какая версия называется "при удалении объектов неполного типа и массивов неклассных и тривиально разрушаемых классов""(мой акцент).

Также кажется, что компиляторы по умолчанию отключают удаление по размеру.

...