Pourquoi les programmeurs C++ devraient-ils éviter new ? Optimisation du code

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

« Why should C++ programmers minimize use of 'new'? » : décryptage d'une question culte



Si vous avez déjà jeté un œil sur Stack Overflow à la recherche de réponses sur le C++, vous avez sûrement vu cette question. Elle a recueilli des milliers de votes et des dizaines de milliers de vues. Et ce n'est pas pour rien. Pour un débutant, le sujet semble contre-intuitif : « Comment ça ? En Java ou en C#, j'écris constamment new, et c'est normal. Pourquoi en C++ ce serait soudainement mauvais ? »



Aujourd'hui, nous ne nous contenterons pas de traduire la réponse du forum anglophone. Nous allons détailler point par point pourquoi la minimisation de new en C++ n'est pas un caprice de gourou, mais une question de performance, de sécurité et de bon sens. Et oui, nous allons écrire du code, regarder l'assembleur (presque) et compter les nanosecondes.



Où va la mémoire : pile vs tas



Avant de parler de new, rappelons les fondamentaux. En C++, il existe deux endroits principaux pour stocker des données :



  • La pile (stack) — petite, rapide, gérée automatiquement. Dès qu'une variable sort de la portée, elle est détruite. Instantanément.
  • Le tas (heap) — grand, lent, nécessite une gestion manuelle. Pour obtenir de la mémoire là-bas, il faut appeler new (ou malloc). Pour la libérer — delete.


Chaque appel à new n'est pas simplement « donne-moi de la mémoire ». C'est un appel système complexe, une recherche de bloc libre, une mise à jour des structures de gestion. C'est des centaines de fois plus lent qu'une allocation sur la pile.



Exemple n°1 : Comparaison de vitesse



#include <chrono>#include <iostream>#include <vector>

struct Point { double x, y, z;};

int main() { const int N = 1000000;

// Allocation sur la pile (tableau sur la pile) auto start = std::chrono::high_resolution_clock::now(); Point points_stack[1000]; // 1000 objets sur la pile auto end = std::chrono::high_resolution_clock::now(); std::cout << "Stack time: " << std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() << " ns";

// Allocation dynamique via new start = std::chrono::high_resolution_clock::now(); std::vector<Point*> points_heap; for (int i = 0; i < 1000; ++i) { points_heap.push_back(new Point()); } end = std::chrono::high_resolution_clock::now(); std::cout << "Heap (new) time: " << std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() << " ns";

// Nettoyage (obligatoire !) for (auto p : points_heap) delete p;

return 0;}


Résultat (sur une machine typique) :

Stack time: 0 nsHeap (new) time: 45200 ns


Une différence de dizaines de milliers de fois. Bien sûr, c'est un test synthétique, mais il montre clairement : chaque new superflu, ce sont des microsecondes retirées de votre budget de performance.



Le problème principal de new : fuites et fragmentation



Si ce n'était qu'une question de vitesse, ce ne serait que la moitié du problème. Mais new entraîne tout un tas de problèmes :



1. Fuites de mémoire (memory leaks)

Vous avez oublié d'appeler delete ? Félicitations, vous avez une fuite. Le programme tourne une heure, un jour, une semaine — et soudainement plante avec std::bad_alloc. Un grand classique. Les fuites sont particulièrement dangereuses dans les processus longs (serveurs, jeux, GUI).



2. Pointeurs pendants (dangling pointers)

Vous avez supprimé l'objet, mais le pointeur est resté. Toute utilisation de ce pointeur est un comportement indéfini (UB). Le programme peut fonctionner, peut planter, peut remplacer votre musique par du techno. UB est un fléau.



3. Fragmentation du tas

Les new/delete fréquents fragmentent le tas en petits morceaux. Même si la mémoire est suffisante, il devient impossible d'allouer un gros bloc. C'est ce qu'on appelle la fragmentation externe.

Blogs

Book Recommendations