Как оператор «удалить это» делает именно? - PullRequest
3 голосов
/ 10 июля 2019

Я просто проверяю оператор на предмет «удалить это». С системным вызовом дескриптора «new / delete» будет потерян один вызов функции удаления перезаписи.

Функция дескриптора имеет вид:

inline void* operator new(size_t size)
{
    void* p = ::malloc( size );
    fprintf( stderr, "new size %ld: %p\n", size, p );
    return p; 
}

inline void* operator new[]( size_t size )
{
    void* p = ::malloc( size );
    fprintf( stderr, "new size[] %ld: %p\n", size, p );
    return p; 
}

inline void  operator delete(void* p)    
{
    fprintf( stderr, "delete: %p\n", p );
    ::free(p); 
}

inline void  operator delete[](void* p)  
{
    fprintf( stderr, "delete []: %p\n", p );
    ::free(p); 
}

и тестовый класс:

class A
{
    public:
        A() : a(NULL)
        {
            printf( "A construct\n" );
            a = new int[100];
        }

        ~A()
        {
            printf( "A destruct \n" );
            freeA();
        }

        void freeA()
        {
            if ( a ) { delete [] a; a = NULL; }
        }

        void release()
        {
            delete this;
        }

    private:
        int*    a;
};

Когда я звоню

A* a = new A();
a->release();

В результате:

new size 8: 0x5642fc1c4e70
A construct
new size[] 400: 0x5642fc1c52a0
A destruct 
delete []: 0x5642fc1c52a0

отсутствует вызов удаления о A (0x5642fc1c4e70),почему?

Ответы [ 4 ]

0 голосов
/ 10 июля 2019

Поскольку вы определили деструктор, нет необходимости определять функцию освобождения.Используйте delete непосредственно на указателе экземпляра

Вместо

A* a = new A();
a->release();

у вас будет

A* a = new A();
delete a;

удаление, вызовет деструктор ~ A ()

0 голосов
/ 10 июля 2019

https://timsong -cpp.github.io / cppwp / replacement.functions # 3

Определения программы используются вместо версий по умолчанию предоставляется реализацией ([support.dynamic]). Такая замена происходит до запуска программы ([basic.def.odr], [basic.start]). объявления программы не должны быть указаны как встроенные. Нет диагностики требуется.

Это правила. Встроенный не допускается. По этой причине вам не хватает одного удаления, и оно работает без встроенных спецификаторов.

0 голосов
/ 10 июля 2019

Я запускаю ваш код ниже c ++ 14, ваш оператор delete может быть вызван правильно.

https://onlinegdb.com/S1zAgzXbB

Однако, работает поверх версии c ++ 14 (включая c++ 14), затем необходимо изменить код с inline void operator delete(void* p) на inline void operator delete(void* p,std::size_t sz) или удалить ключевое слово inline.тогда ваш код будет работать правильно

https://onlinegdb.com/BJ3hMz7WH

надеюсь, вам это поможет.

0 голосов
/ 10 июля 2019

Я только что обнаружил проблему: при inline оператор delete (void * p) вообще не может вызвать. Но удалить [] (void * p) можно. Теперь я закрою это.

...