Je tente de remplacer les opérateurs globaux new et delete par XCode 3.2, GCC 4.2, libstdC++ 4.0, version dynamique.Remplacement de libstdC++. Dylib (4.0) opérateurs globaux nouveaux et supprimés sous OSX
J'ai pris les prototypes directement à partir de l'en-tête "nouveau" et les ai implémentés. Ils sont collés ci-dessous.
Le projet est un .plugin donc une lib dynamique. Ce plug-in DOIT déléguer l'allocation aux propres routines alloc/free de l'application principale, qui se trouvent dans un ancien SDK C.
Tous mes propres appels à new/delete avec les allocations std :: list et std :: map sont correctement remplacés, MAIS pas quand std :: vector :: push_back doit augmenter son buffer. Dans ce cas, mon opérateur new n'est pas appelé mais mon opérateur delete est. Je le sais, car j'écris un token dans les quatre premiers octets de tout buffer alloué par mon nouvel opérateur et je vérifie ce jeton dans l'opérateur delete. Voir ci-dessous pour le code incriminé.
extern "C++"
{
__attribute__((visibility("default"))) void* operator new(std::size_t) throw (std::bad_alloc);
__attribute__((visibility("default"))) void* operator new[](std::size_t) throw (std::bad_alloc);
__attribute__((visibility("default"))) void operator delete(void*) throw();
__attribute__((visibility("default"))) void operator delete[](void*) throw();
__attribute__((visibility("default"))) void* operator new(std::size_t, const std::nothrow_t&) throw();
__attribute__((visibility("default"))) void* operator new[](std::size_t, const std::nothrow_t&) throw();
__attribute__((visibility("default"))) void operator delete(void*, const std::nothrow_t&) throw();
__attribute__((visibility("default"))) void operator delete[](void*, const std::nothrow_t&) throw();
}
Le code suivant provoque une assertion quand « yo » est hors de portée, car la mémoire allouée pour le std :: vecteur n'a pas été affecté par mon opérateur nouveau.
{
std::vector<std::string> yo;
yo.push_back("yoyoma");
yo.push_back("yoyoma");
yo.push_back("yoyoma");
yo.push_back("yoyoma");
}
Le code suivant est ok parce que std :: vector :: réserve appelle mon nouvel opérateur:
{
std::vector<std::string> yo;
yo.reserve(4);
yo.push_back("yoyoma");
yo.push_back("yoyoma");
yo.push_back("yoyoma");
yo.push_back("yoyoma");
}
GBD (débogueur) ne laissera pas rencontré pas dans le std :: vector :: Push_back implémentation quand il a besoin de développer le tampon (la méthode est nommée _M_insert_aux). Tout ce que je sais, c'est que mon opérateur new n'est jamais appelé depuis std :: vector :: push_back.
La solution de contournement ci-dessus ne peut pas être appliquée à toutes les bibliothèques tierces que j'utilise. L'un d'entre eux est un gros utilisateur de push_back.
J'ai essayé de lier statiquement à libstdC++. A mais j'ai le même problème.
Y a-t-il une spécialisation pour std :: vector std :: string> qui n'utilise pas le nouvel opérateur global?
BTW cela a fonctionné parfaitement sur windows avec VS9.
Un moyen plus fiable de vérifier si vous recevez un appel est d'insérer un point d'arrêt avant d'appeler l'API de l'application. – Potatoswatter