La préallocation est souvent évoquée (à juste titre), mais ca serait pas mal de préciser que ca peut avoir des conséquences imprévues
J'ai tout récemment eu un problème sur un std::vector<> ou le bug a été difficile à identifier à cause ce ça.
Exemple, cette abbération marche:
std::vector<int> v;
v.reserve(10);
v[0] = 42;
std::cout << "VAL=" << v.front() << std::endl;
Le truc c'est que seule la fonction std::vector.at() contrôle les erreurs de débordement, pas l'opérateur [], back() ou front(). C'est d'ailleurs précisé dans la norme: https://en.cppreference.com/w/cpp/container/vector
Mon cas a été plus tordu, puisque qu'à cause d'une erreur dans mon code, je modifiais mon vecteur avec back() sans qu'il y ait eu de push_back() au préalable.
Ce qui a eu conséquence (sans que je comprenne exactement pourquoi) de faire planter le programme au moment de l'appel du destructeur.
SIGABRT : double free or corruption
Le mauvais côté c'est que si j'avais pas utilisé reserve(), le programme aurait planté dès l'appel à back(), ce qui m'aurait dirigé directement à la source de l'erreur.
Du coup c'est très bien dans l'idée mais maintenant je ne réserverai plutôt à du code de production.
# Petit retour d'expérience.
Posté par Florian.J . En réponse au lien Effortless Performance Improvements in C++: std::vector. Évalué à 1. Dernière modification le 26 mars 2023 à 18:03.
La préallocation est souvent évoquée (à juste titre), mais ca serait pas mal de préciser que ca peut avoir des conséquences imprévues
J'ai tout récemment eu un problème sur un std::vector<> ou le bug a été difficile à identifier à cause ce ça.
Exemple, cette abbération marche:
std::vector<int> v;
v.reserve(10);
v[0] = 42;
std::cout << "VAL=" << v.front() << std::endl;
Le truc c'est que seule la fonction std::vector.at() contrôle les erreurs de débordement, pas l'opérateur [], back() ou front(). C'est d'ailleurs précisé dans la norme:
https://en.cppreference.com/w/cpp/container/vector
Mon cas a été plus tordu, puisque qu'à cause d'une erreur dans mon code, je modifiais mon vecteur avec back() sans qu'il y ait eu de push_back() au préalable.
Ce qui a eu conséquence (sans que je comprenne exactement pourquoi) de faire planter le programme au moment de l'appel du destructeur.
SIGABRT : double free or corruption
Le mauvais côté c'est que si j'avais pas utilisé reserve(), le programme aurait planté dès l'appel à back(), ce qui m'aurait dirigé directement à la source de l'erreur.
Du coup c'est très bien dans l'idée mais maintenant je ne réserverai plutôt à du code de production.