Bagikan melalui


Compiler Error C2956

fungsi dealokasi biasa 'fungsi' akan dipilih sebagai fungsi dealokasi penempatan

Keterangan

Fungsi dealokasi yang ditemukan untuk ekspresi baru penempatan cocok dengan salah satu fungsi dealokasi yang biasa. Baik dealokasi implisit yang dihasilkan kompilator atau eksplisit delete (atau delete[]) akan menggunakan fungsi dealokasi yang salah.

Kesalahan C2956 menunjukkan Anda menggunakan ekspresi baru penempatan ( new ekspresi yang mengambil parameter) dengan cara yang dapat menyebabkan kebocoran memori atau crash runtime. Biasanya berarti nilai yang dihasilkan tidak dapat dihapus dengan cara yang khas. Artinya, ekspresi eksplisit delete (atau delete[]) dalam kode Anda, atau kesepakatan implisit ketika konstruktor melempar pengecualian, dapat memanggil yang salah operator delete atau menyediakannya dengan parameter yang salah.

Standar C++ menentukan fungsi dealokasi biasa sebagai kelebihan beban operator delete atau operator delete[] yang mengambil parameter tambahan jenis std::size_t (C++14 atau yang lebih baru), std::align_val_t (C++17 atau yang lebih baru), dan std::destroying_delete_t (C++20 atau yang lebih baru). Saat Anda menggunakan ekspresi baru penempatan, pengkompilasi mencari fungsi yang cocok operator delete yang mengambil parameter yang sama (setelah yang pertama). Jika ditemukan dan tanda tangannya cocok dengan fungsi dealokasi biasa, kompilator melaporkan kesalahan C2956.

Cara untuk mengatasi masalah bergantung pada niat Anda. Misalnya, di C++11, Anda dapat menentukan operator new kelebihan beban yang mengambil parameter tambahan size_t di kelas Anda untuk meneruskan nilai ke alokator. Di C++14, kode yang sama sekarang menyebabkan kesalahan:

#include <new>
struct T {
    void* operator new(std::size_t, std::size_t); // Placement allocation function
    void operator delete(void*, std::size_t); // now considered a usual deallocation function
};

T* p = new (0) T;   // error: usual deallocation function would be chosen as placement deallocation function

Jika niat Anda adalah menentukan memori yang terlalu selaras untuk objek, Anda dapat menentukan perataan langsung pada jenis dengan menggunakan alignas. Untuk informasi selengkapnya tentang alignas, lihat Perataan.

Jika niat Anda adalah menentukan memori yang terlalu selaras untuk jenis asli yang dialokasikan timbunan atau array, bungkus dalam struct atau class yang memiliki penentu alignas . Kemudian normal new dan delete ekspresi dapat mengalokasikan dan membatalkan alokasi instans yang memiliki perataan yang Anda maksudkan.

Contoh

Dalam contoh ini, new-expression menggunakan sintaks penempatan dengan argumen jenis std::align_val_t. Namun, karena jenis T tidak menentukan persyaratan perataan, delete-expression pada T* tidak akan memanggil fungsi dealokasi yang terlalu selaras yang cocok. Sebaliknya, kompilator akan memanggil fungsi void operator delete(void* ptr) noexceptdealokasi biasa , yang tidak menangani alokasi yang terlalu selaras. Daripada menyebabkan crash atau kebocoran memori, pengkompilasi melaporkan kesalahan untuk penggunaan penempatan newini :

#include <new>
struct T {};

int main()
{
    T* p = new (std::align_val_t{64}) T; // C2956
    delete p; // ordinary, not over-aligned delete
}

Untuk mengatasi masalah ini, terapkan penentu alignas ke T:

#include <new>
struct alignas(64) T {};

int main()
{
    T* p = new T; // invokes ::operator new(std::size_t, std::align_val_t)
    delete p; // now invokes ::operator delete(void*, std::align_val_t)
}