Bonjour,
Je souhaiterais pouvoir interdire l'utilisation de l'opérateur new à partir d'un certain moment dans mon code. Du coup, je me dis que de le redéfinir est la solution. Mais je ne vois pas comment.
Cordialement,
Julien.
Bonjour,
Je souhaiterais pouvoir interdire l'utilisation de l'opérateur new à partir d'un certain moment dans mon code. Du coup, je me dis que de le redéfinir est la solution. Mais je ne vois pas comment.
Cordialement,
Julien.
Si tu veux empêcher quelqu'un d'instancier une classe en particulier, il te suffit de déclarer les constructeurs en privé.
Si vraiment tu veux redéfinir new, c'est possible:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 class C { public: void* operator new (size_t size, autres parametres); }
les raisonnables ont duré, les passionné-e-s ont vécu
Bonjour,
A ta place, je passerais par une factory générique (enfin, en réalité à ta place, je réfléchirai 2 ou 3 fois de plus à savoir pourquoi je veux faire cette opération des plus étranges et voir ce qui peut être fait de bien plus belle manière à cette fin).
Par contre je laisse de côté les paramètres du constructeur (sûrement très simple à ajouter en C++11, moins sans ça je trouve).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 class Factory { template<class T> static bool New(T*& t) { t = NULL; if (canConstruct()) { t = new T; return true; } return false; } template<class T> static bool NewArray(T*& t, unsigned int size) { t = NULL; if (canConstruct()) { t = new T[size]; return true; } return false; } // return false pour interdire la construction static bool canConstruct() { return true; } }; int* array; if (Factory::NewArray(array, 10)) { // manipulation de mon array[10] correctement créé delete[] array; }
Du coup je m'interdis aussi les déclarations sans pointeur.
Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
Un peu de programmation réseau ?
Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.
Merci pour vos réponses.
Alors l'intérêt d'interdire une allocation mémoire dynamique est du au fait que l'on est dans un contexte de système embarqué. Il y a donc une étape de configuration au démarrage pendant laquelle les allocations sont autorisées, puis interdites par la suite (d'ou le "à partir d'un moment").
Julien.
Là, c'est une autre paire de manche.
Il s'agit d'interdire toute allocation dynamique, pas seulement celles de quelques classes.
Le mieux, c'est de spécifier ce comportement, et de taper sur tout développeur qui ne s'y soumet pas
Mes principes de bases du codeur qui veut pouvoir dormir:Pour faire des graphes, essayez yEd.
- Une variable de moins est une source d'erreur en moins.
- Un pointeur de moins est une montagne d'erreurs en moins.
- Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
- jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
- La plus sotte des questions est celle qu'on ne pose pas.
le ter nel est le titre porté par un de mes personnages de jeu de rôle
Oui voila, la difficulté est qu'il faut vraiment interdire tout type d'allocation dynamique. Je t'avouerai que j'avais pensé à ta solution =). Après bon effectivement sur des "petits" projets un simple mot peut suffire, mais pour de la programmation multi-sites (France, Angleterre, Chine, ...) il y aura toujours quelqu'un qui ne respectera pas cette règle
Julien.
Une spécification est un "commandement divin devant absolument être suivi sous peine de rejet du projet par le client". Spécifier, c'est donner un ordre qui ne peut pas être refusé.
Cela dit, l'interdiction posée bloque aussi l'utilisation des string, des collections, et des lazy-singletons et j'en passe.
Dans ce cas, tu peux tricher violemment, en imposant une redéfinition à la compilation de malloc et new via une macro. Je pense à -Dnew="null;exit(-1);//" ou -Dnew="null;throw 0;//" (ou la variante #define en forçant l'inclusion du .h le contenant par la spec)
Mais c'est probablement trop violent.
Mais si le problème est la taille mémoire, un gros paquets de variable aura le même effet qu'un new: l'encombrement.
Du coup, pour quelle raison veux-tu interdire totalement l'allocation dynamique?
Mes principes de bases du codeur qui veut pouvoir dormir:Pour faire des graphes, essayez yEd.
- Une variable de moins est une source d'erreur en moins.
- Un pointeur de moins est une montagne d'erreurs en moins.
- Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
- jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
- La plus sotte des questions est celle qu'on ne pose pas.
le ter nel est le titre porté par un de mes personnages de jeu de rôle
Le système en cours de programmation NE devra JAMAIS rebooter et devra rester en marche des mois voire des années. De plus, pendant cette période, il communiquera avec d'autres systèmes, et des données seront transférées toutes les X ms. Du coup, si une allocation mémoire échoue (ce qui peut arriver) à un moment M, il y a un risque de pertes de données. De plus, nous ne sommes pas limités en espace mémoire. Donc l'utilisation de taille fixe ne nous pose pas de problèmes.
En gros, le système a le droit de "planter" pendant la phase de configuration mais pas après.
Il faut déjà commencer par être clair avec toi même.
Tu veux interdire new après la phase de configuration. Certes. Cela veut il dire que tu ne pourra plus utiliser de std::vector Tous tes tableaux devront être de taille fixe dès le début ? Pas de std::string ? ...
Car si tu veux interdire tous les new que les utilisateurs peuvent écrire, suffit d'une macro dans ce genre
C'est certes degeulasse, mais efficace.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include <iostream> #include <vector> using namespace std; template<int> struct CompileTimeError; template<> struct CompileTimeError<true> {}; #define static_check(expr, msg) \ { CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; } #define new static_check(0,_NEW_NOT_ALLOWED) int main(void) { std::vector<int> foo; foo.push_back(5); std::cout<<foo.size()<<std::endl; // int* p=new int; //retire le commentaire et ca plante int i=5; ++i; std::cout<<i<<" "<<foo[0]<<std::endl; }
Si quelqu'un a une solution moins crade, je suis preneur (surcharge propre de new ?).
"Never use brute force in fighting an exponential." (Andrei Alexandrescu)
Mes articles dont Conseils divers sur le C++
Une très bonne doc sur le C++ (en) Why linux is better (fr)
je suis pas sur que ca doit etre fait at runtime.
tu devrais plutot localiser ta conf/load dans un dossier, et faire un bon vieux grep sur les autres dossiers (mettant en jeux le fonctionnement normal (la phase running))
edit: pas vu message de 13h06, mais l'idee est la meme
N'utilisez-vous pas de review de code où vous pouvez définir des règles comme interdire l'opérateur new ?
Par contre comme les autres, je trouve ça léger comme règle pour s'assurer que la mémoire ira bien. Rien n'interdira de créer un tableau statique qui fasse exploser la mémoire après tout.
Et finalement, dynamique ou statique c'est surtout une question de portée des données : doivent-elles subsister ou non en dehors du scope de leur déclaration ?
Mais dans l'absolu, c'est très similaire.
Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
Un peu de programmation réseau ?
Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.
Bonjour,
Tu peux te faire un allocateur perso, tu réserves un plage de données au début et après tu tapes dedans à chaque fois. Par contre il faudra pas oublie de l'utiliser (spécifer le paramètre optionnel des conteneurs par exemple). Pour l'implémentation, recherche sur internet des articles détaillant la mise en place d'allocateur pour les petits objets, le raisonnement est assez proche (sauf que les objets sont pas petits et que la zone aura une taille fixe).
Par contre je suis assez sceptique quand au réel interêt, tu ne peux vraiment pas faire confiance au système ? Quel est la probabilité qu'une allocation échoue (sachant que ca ne peut pas être à cause d'un manque de mémoire comme tu le sous-entend) ?
Oui effectivement, cela ouvre une autre question à laquelle je n'ai pas la réponse: quel est la probabilité d'une erreur d'allocation mémoire ? D'ailleurs, une allocation mémoire échoue t-elle seulement en cas de mémoire insuffisante ?
Enfin bon faudra que je me documente sur ce point ^^.
Merci à vos réponses, c'est toujours intéressant d'avoir des critiques sur des méthodes de programmation.
Julien.
Mieux vaut avoir des allocations surveillées (catch des exceptions, controles des retours) plutot que de les interdires.
J'imagine mal quelqu'un dire: "Voici une voiture, je vous mets deux litres d'essences, rendez-vous à l'autre bout du monde. Oh! J'oubliais, j'ai soudé le bouchon du réservoir..."
Mes principes de bases du codeur qui veut pouvoir dormir:Pour faire des graphes, essayez yEd.
- Une variable de moins est une source d'erreur en moins.
- Un pointeur de moins est une montagne d'erreurs en moins.
- Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
- jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
- La plus sotte des questions est celle qu'on ne pose pas.
le ter nel est le titre porté par un de mes personnages de jeu de rôle
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager