A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://en.cppreference.com/w/cpp/language/../memory/shared_ptr/../new/operator_delete.html below:

operator delete, operator delete[] - cppreference.com

Replaceable usual deallocation functions

(1)

void operator delete  ( void* ptr ) throw();

(until C++11)

void operator delete  ( void* ptr ) noexcept;

(since C++11) (2)

void operator delete[]( void* ptr ) throw();

(until C++11)

void operator delete[]( void* ptr ) noexcept;

(since C++11) (3) (since C++17) (4) (since C++17) void operator delete  ( void* ptr, std::size_t sz ) noexcept; (5) (since C++14) void operator delete[]( void* ptr, std::size_t sz ) noexcept; (6) (since C++14) (7) (since C++17) (8) (since C++17)

Replaceable placement deallocation functions

(9) void operator delete  ( void* ptr, const std::nothrow_t& tag ) throw(); (until C++11) void operator delete  ( void* ptr, const std::nothrow_t& tag ) noexcept; (since C++11) (10) void operator delete[]( void* ptr, const std::nothrow_t& tag ) throw(); (until C++11) void operator delete[]( void* ptr, const std::nothrow_t& tag ) noexcept; (since C++11) (11) (since C++17) (12) (since C++17)

Non-allocating placement deallocation functions

(13)

void operator delete  ( void* ptr, void* place ) throw();

(until C++11)

void operator delete  ( void* ptr, void* place ) noexcept;

(since C++11) (14)

void operator delete[]( void* ptr, void* place ) throw();

(until C++11)

void operator delete[]( void* ptr, void* place ) noexcept;

(since C++11)

User-defined placement deallocation functions

void operator delete  ( void* ptr, args... );

(15)

void operator delete[]( void* ptr, args... );

(16)

Class-specific usual deallocation functions

void T::operator delete  ( void* ptr );

(17)

void T::operator delete[]( void* ptr );

(18) (19) (since C++17) (20) (since C++17) (21) void T::operator delete[]( void* ptr, std::size_t sz ); (22) (23) (since C++17) (24) (since C++17)

Class-specific placement deallocation functions

void T::operator delete  ( void* ptr, args... );

(25)

void T::operator delete[]( void* ptr, args... );

(26)

Class-specific usual destroying deallocation functions

(27) (since C++20) (28) (since C++20) (29) (since C++20) (30) (since C++20)

Deallocates storage previously allocated by a matching operator new or operator new[]. These deallocation functions are called by delete and delete[] expressions and by placement new expressions to deallocate memory after destructing (or failing to construct) objects with dynamic storage duration. They may also be called using regular function call syntax.

1-12) Replaceable

deallocation functions. The standard library provides default implementations for these functions, for the effects of the default implementations, see

below

.

1-8) Called by delete and delete[] expressions. Invalidates any non-null ptr.

9-12)

Called by placement

new

expressions upon

initialization failure

.

operator delete[]

invalidates any non-null

ptr

.

If ptr is not a null pointer and one of the following conditions is satisfied, the behavior is undefined:

15-30) User-defined deallocation functions called by delete, delete[] and placement new expressions.

27-30) If defined, delete expressions does not execute the destructor for *ptr before placing a call to operator delete. Instead, direct invocation of the destructor such as by ptr->~T(); becomes the responsibility of this operator delete.

Overloads (1-8) are implicitly declared in each translation unit even if the <new> header is not included.

See delete expression for the criteria of selecting overload.

[edit] Parameters ptr - pointer to a memory block to deallocate or a null pointer sz - the size that was passed to the matching allocation function place - pointer used as the placement parameter in the matching placement new tag - overload disambiguation tag matching the tag used by non-throwing operator new al - alignment of the object or array element that was allocated args - arbitrary parameters matching a placement allocation function (may include std::size_t and std::align_val_t) [edit] Exceptions

All deallocation functions are noexcept(true) unless specified otherwise in the declaration.

(since C++11)

If a deallocation function terminates by throwing an exception, the behavior is undefined, even if it is declared with noexcept(false)(since C++11).

[edit] Global replacements

Overloads (1-12) are replaceable. The effects of the default versions are:

1)

If

ptr

is null, does nothing. Otherwise, reclaims the storage allocated by the earlier call to

operator new

.

2)

Calls

operator delete(ptr)

as if overload

(1)

can reclaim the storage allocated by the earlier call to

operator new[]

.

3) Same as (1).

4)

Calls

operator delete(ptr, al)

as if overload

(3)

can reclaim the storage allocated by the earlier call to

operator new[]

.

5) Calls operator delete(ptr).

6) Calls operator delete[](ptr).

7) Calls operator delete(ptr, al).

8) Calls operator delete[](ptr, al).

9) Calls operator delete(ptr).

10) Calls operator delete[](ptr).

11) Calls operator delete(ptr, al).

12) Calls operator delete[](ptr, al).

Global operators new/delete replacement:

#include <cstdio>
#include <cstdlib>
#include <new>
 
// no inline, required by [replacement.functions]/3
void* operator new(std::size_t sz)
{
    std::printf("1) new(size_t), size = %zu\n", sz);
    if (sz == 0)
        ++sz; // avoid std::malloc(0) which may return nullptr on success
 
    if (void *ptr = std::malloc(sz))
        return ptr;
 
    throw std::bad_alloc{}; // required by [new.delete.single]/3
}
 
// no inline, required by [replacement.functions]/3
void* operator new[](std::size_t sz)
{
    std::printf("2) new[](size_t), size = %zu\n", sz);
    if (sz == 0)
        ++sz; // avoid std::malloc(0) which may return nullptr on success
 
    if (void *ptr = std::malloc(sz))
        return ptr;
 
    throw std::bad_alloc{}; // required by [new.delete.single]/3
}
 
void operator delete(void* ptr) noexcept
{
    std::puts("3) delete(void*)");
    std::free(ptr);
}
 
void operator delete(void* ptr, std::size_t size) noexcept
{
    std::printf("4) delete(void*, size_t), size = %zu\n", size);
    std::free(ptr);
}
 
void operator delete[](void* ptr) noexcept
{
    std::puts("5) delete[](void* ptr)");
    std::free(ptr);
}
 
void operator delete[](void* ptr, std::size_t size) noexcept
{
    std::printf("6) delete[](void*, size_t), size = %zu\n", size);
    std::free(ptr);
}
 
int main()
{
    int* p1 = new int;
    delete p1;
 
    int* p2 = new int[10]; // guaranteed to call the replacement in C++11
    delete[] p2;
}

Possible output:

// Compiled with GCC-5 in C++17 mode to obtain the following:
1) op new(size_t), size = 4
4) op delete(void*, size_t), size = 4
2) op new[](size_t), size = 40
5) op delete[](void* ptr)

Overloads of operator delete and operator delete[] with additional user-defined parameters ("placement forms", (15,16)) may be declared at global scope as usual, and are called by the matching placement forms of new expressions if a constructor of the object that is being allocated throws an exception.

The standard library placement forms of operator delete and operator delete[] (13,14) cannot be replaced and can only be customized if the placement new expression did not use the ::new syntax, by providing a class-specific placement delete (25,26) with matching signature: void T::operator delete(void*, void*) or void T::operator delete[](void*, void*).

[edit] Class-specific overloads

Deallocation functions (17-24) may be defined as static member functions of a class. These deallocation functions, if provided, are called by delete expressions when deleting objects (17,19,21) and arrays (18,20,22) of this class, unless the delete expression used the form ::delete which bypasses class-scope lookup. The keyword static is optional for these function declarations: whether the keyword is used or not, the deallocation function is always a static member function.

The delete expression looks for appropriate deallocation function's name starting from the class scope (array form looks in the scope of the array element class) and proceeds to the global scope if no members are found as usual. Note, that as per name lookup rules, any deallocation functions declared in class scope hides all global deallocation functions.

If the static type of the object that is being deleted differs from its dynamic type (such as when deleting a polymorphic object through a pointer to base), and if the destructor in the static type is virtual, the single object form of delete begins lookup of the deallocation function's name starting from the point of definition of the final overrider of its virtual destructor. Regardless of which deallocation function would be executed at run time, the statically visible version of operator delete must be accessible in order to compile. In other cases, when deleting an array through a pointer to base, or when deleting through pointer to base with non-virtual destructor, the behavior is undefined.

If the single-argument overload (17,18) is not provided, but the size-aware overload taking std::size_t as the second parameter (21,22) is provided, the size-aware form is called for normal deallocation, and the C++ runtime passes the size of the object to be deallocated as the second argument. If both forms are defined, the size-unaware version is called.

#include <cstddef>
#include <iostream>
 
// sized class-specific deallocation functions
struct X
{
    static void operator delete(void* ptr, std::size_t sz)
    {
        std::cout << "custom delete for size " << sz << '\n';
        ::operator delete(ptr);
    }
 
    static void operator delete[](void* ptr, std::size_t sz)
    {
        std::cout << "custom delete for size " << sz << '\n';
        ::operator delete[](ptr);
    }
};
 
int main()
{
    X* p1 = new X;
    delete p1;
 
    X* p2 = new X[10];
    delete[] p2;
}

Possible output:

custom delete for size 1
custom delete for size 18

Overloads of operator delete and operator delete[] with additional user-defined parameters ("placement forms", (25,26)) may also be defined as class members. When the failed placement new expression looks for the corresponding placement delete function to call, it begins lookup at class scope before examining the global scope, and looks for the function with the signature matching the placement new:

#include <cstddef>
#include <iostream>
#include <stdexcept>
 
struct X
{
    X() { throw std::runtime_error("X(): std::runtime_error"); }
 
    // custom placement new
    static void* operator new(std::size_t sz, bool b)
    {
        std::cout << "custom placement new called, b = " << b << '\n';
        return ::operator new(sz);
    }
 
    // custom placement delete
    static void operator delete(void* ptr, bool b)
    {
        std::cout << "custom placement delete called, b = " << b << '\n';
        ::operator delete(ptr);
    }
};
 
int main()
{
    try
    {
        [[maybe_unused]] X* p1 = new (true) X;
    }
    catch (const std::exception& ex)
    {
        std::cout << ex.what() << '\n';
    }
}

Output:

custom placement new called, b = 1
custom placement delete called, b = 1
X(): std::runtime_error

If class-level operator delete is a template function, it must have the return type of void, the first argument void*, and it must have two or more parameters. In other words, only placement forms can be templates. A template instance is never a usual deallocation function, regardless of its signature. The specialization of the template operator delete is chosen with template argument deduction.

[edit] Notes

The call to the class-specific T::operator delete on a polymorphic class is the only case where a static member function is called through dynamic dispatch.

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior CWG 220 C++98 user-defined deallocation functions were permitted to throw throwing from a deallocation function
results in undefined behavior CWG 1438 C++98 any use of an invalid pointer value was undefined behavior only indirection and deallocation are LWG 206 C++98 replacing (2) did not affect the default behavior of (10) the default behavior
changes accordingly LWG 298 C++98 replacing (1) did not affect the default behavior of (9) the default behavior
changes accordingly LWG 404 C++98 replacements of the replaceable deallocation
functions could be declared inline prohibited, no diagnostic required LWG 2458 C++14 overloads taking (void*, std::size_t, const
std::nothrow_t&) were specified, but could never be called removed spurious overloads [edit] See also

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4