Sdílet prostřednictvím


Chyba kompilátoru C2956

jako funkce přidělení umístění by byla zvolena funkce "function".

Poznámky

Funkce deallocation nalezená pro umístění nového výrazu odpovídá jedné z obvyklých funkcí deallocation. Buď implicitní kompilátor vygenerovaný deallocation, nebo explicitní delete (nebo delete[]) by použil nesprávnou funkci deallocation.

Chyba C2956 označuje, že jste použili , který přebírá parametry) způsobem, který může způsobit nevracení paměti nebo chybu modulu runtime. Obvykle to znamená, že výslednou hodnotu nelze obvyklým způsobem odstranit. To znamená, že buď explicitní delete (nebo delete[]) výraz v kódu, nebo implicitní deallocation, když konstruktor vyvolá výjimku, může vyvolat nesprávné operator delete nebo zadat nesprávné parametry.

Standard C++ určuje obvyklé funkce uvolnění jako přetížení operator delete nebo operator delete[] které přebírají další parametry typu std::size_t (C++14 nebo novější), std::align_val_t (C++17 nebo novější) a std::destroying_delete_t (C++20 nebo novější). Při použití nového výrazu umístění hledá kompilátor odpovídající operator delete funkci, která přebírá stejné parametry (za prvním výrazem). Pokud se najde a jeho podpis odpovídá obvyklé funkci přidělení, kompilátor hlásí chybu C2956.

Způsob řešení problému závisí částečně na vašem záměru. Například v jazyce C++11 můžete definovat operator new přetížení, které vezme ve třídě další size_t parametr, který předá hodnotu alokátoru. V jazyce C++14 teď stejný kód způsobí chybu:

#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

Pokud je vaším záměrem zadat pro objekt zarovnanou paměť, můžete místo toho určit zarovnání přímo na typ pomocí alignas. Další informace o alignastom naleznete v tématu Zarovnání.

Pokud vaším záměrem je zadat zarovnanou paměť pro nativní typ haldy nebo pole, zabalte ho struct do specifikátoru class nebo alignas který má specifikátor. Pak mohou normální new výrazy delete a přidělit a uvolnit instance, které mají zamýšlený zarovnání.

Příklad

V tomto příkladu new-expression používá syntaxi umístění s argumentem typu std::align_val_t. Vzhledem k tomu, že typ T nezadá požadavek na zarovnání, delete-expression nevyvolá funkce T* přidělení odpovídající přerovnané funkce přidělení. Místo toho by kompilátor vyvolal obvyklou funkci void operator delete(void* ptr) noexceptpřidělení, která nezpracovává přerovnané přidělení. Místo toho, aby došlo k chybovému ukončení nebo nevrácení paměti, kompilátor hlásí chybu pro toto umístění new:

#include <new>
struct T {};

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

Pokud chcete tento problém vyřešit, použijte specifikátor alignasproT:

#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)
}