Erreur du compilateur C2956
la fonction de désallocation habituelle 'fonction' est choisie en tant que fonction de désallocation de position
La fonction de désallocation trouvée pour la nouvelle expression de placement correspond à l’une des fonctions de désallocation habituelles. Soit une désallocation générée par le compilateur implicite, soit une fonction explicite delete
(ou delete[]
) utilise la fonction de désallocation incorrecte.
Notes
L’erreur C2956 indique que vous avez utilisé une nouvelle expression de placement (expression new
qui prend des paramètres) d’une manière qui peut entraîner une fuite de mémoire ou un incident d’exécution. Cela signifie généralement que la valeur résultante ne peut pas être supprimée d’une manière classique. Autrement dit, une expression explicite delete
(ou delete[]
) dans votre code, ou la désallocation implicite lorsqu’un constructeur lève une exception, peut appeler le mauvais operator delete
ou le fournir avec les paramètres incorrects.
La norme C++ spécifie les fonctions de désallocation habituelles en tant que surcharges de operator delete
type ou operator delete[]
qui prennent des paramètres supplémentaires de type std::size_t
(C++14 ou version ultérieure), std::align_val_t
(C++17 ou version ultérieure) et std::destroying_delete_t
(C++20 ou version ultérieure). Lorsque vous utilisez une nouvelle expression de placement, le compilateur recherche une fonction correspondante operator delete
qui prend les mêmes paramètres (après la première). Si l’un est trouvé et que sa signature correspond à une fonction de désallocation habituelle, le compilateur signale l’erreur C2956.
La façon de résoudre le problème dépend en partie de votre intention. Par exemple, en C++11, vous pouvez définir une operator new
surcharge qui prend un paramètre supplémentaire size_t
dans votre classe pour passer une valeur à l’allocateur. En C++14, le même code provoque désormais une erreur :
#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
Si votre intention est de spécifier une mémoire sur-alignée pour un objet, vous pouvez à la place spécifier l’alignement directement sur le type à l’aide alignas
de . Pour plus d’informations sur alignas
, consultez Alignement.
Si votre intention est de spécifier une mémoire sur-alignée pour un type natif alloué au tas ou un tableau, encapsulez-le dans un struct
ou class
qui a le alignas
spécificateur. Ensuite, les expressions normales new
delete
peuvent allouer et libérer des instances qui ont votre alignement prévu.
Exemple
Dans cet exemple, l’utilisation de la new-expression
syntaxe de placement avec un argument de type std::align_val_t
. Toutefois, étant donné que le type T
ne spécifie pas d’exigence d’alignement, un delete-expression
sur un T*
n’appelle pas une fonction de désallocation sur-alignée correspondante. Au lieu de cela, le compilateur appelle la fonction void operator delete(void* ptr) noexcept
de désallocation habituelle, qui ne gère pas une allocation sur-alignée. Au lieu de provoquer un blocage ou une fuite de mémoire, le compilateur signale une erreur pour cette utilisation du placement new
:
#include <new>
struct T {};
int main()
{
T* p = new (std::align_val_t{64}) T; // C2956
delete p; // ordinary, not over-aligned delete
}
Pour résoudre ce problème, appliquez un alignas
spécificateur à 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)
}