18 votes

Pourquoi l'environnement d'exécution ne peut-il pas décider d'appliquer delete ou delete[] à la place du programmeur ?

J'ai lu que la delete[] est nécessaire car l'environnement d'exécution ne sait pas si le bloc alloué est un tableau d'objets nécessitant ou non des appels au destructeur, mais il sait où le bloc alloué est stocké dans la mémoire et, bien sûr, quelle est sa taille.
Il suffirait d'une métadonnée supplémentaire pour se rappeler si les destructeurs doivent être appelés lors d'une suppression ou non, alors pourquoi ne pas le faire ?

Je suis presque sûr qu'il y a une bonne explication, je ne la mets pas en doute, je souhaite simplement la connaître.

10voto

Mark B Points 60200

Je pense que la raison en est que le C++ ne vous oblige pas à faire ce que vous ne voulez pas. Il ajouterait des métadonnées supplémentaires et si quelqu'un ne l'utilisait pas, cette charge supplémentaire lui serait imposée, ce qui est contraire aux objectifs de conception du langage C++.

Lorsque vous souhaitez obtenir la capacité que vous avez décrite, C++ fait fournir un moyen. Il s'appelle std::vector et vous devriez presque toujours le préférer à un autre type de conteneur ou à un pointeur intelligent plutôt qu'à des données brutes. new y delete .

4voto

Austin Heerwagen Points 543

Le C++ vous permet d'être aussi efficace que possible, donc s'ils devaient suivre le nombre d'éléments dans un bloc, cela représenterait simplement 4 octets supplémentaires utilisés par bloc.

Cela peut être utile à beaucoup de gens, mais cela empêche aussi une efficacité totale pour les personnes qui ne voient pas d'inconvénient à mettre [].

C'est un peu comme la différence entre C++ et Java. Java peut être beaucoup plus rapide à programmer parce que vous n'avez jamais à vous soucier du ramassage des ordures, mais C++, s'il est programmé correctement, peut être plus efficace et utiliser moins de mémoire parce qu'il n'a pas besoin de stocker ces variables et que vous pouvez décider quand supprimer les blocs de mémoire.

4voto

smparkes Points 9849

Il s'agit essentiellement d'une conception du langage qui ne veut pas imposer trop de restrictions aux exécutants. De nombreux moteurs d'exécution C++ utilisent malloc() pour ::operator new () y free() (plus ou moins) pour ::operator delete () . Standard malloc / free ne fournissent pas la comptabilité nécessaire à l'enregistrement d'un certain nombre d'éléments et n'offrent aucun moyen de déterminer le nombre d'éléments à enregistrer. malloc La taille de la free temps. L'ajout d'un autre niveau de manipulation de la mémoire entre new Foo y malloc pour chaque objet est, du point de vue de C/C++, un saut assez important dans la complexité/l'abstraction. Entre autres choses, l'ajout de cette surcharge à chaque objet mettrait à mal certaines approches de gestion de la mémoire qui sont conçues en fonction de la taille des objets.

3voto

Matthieu M. Points 101624

Deux choses doivent être clarifiées ici.

Premièrement : l'hypothèse selon laquelle malloc conserve la taille précise demandée.

Pas vraiment. malloc ne se préoccupe que de fournir un bloc suffisamment grand. Bien que, pour des raisons d'efficacité, il ne surallouera probablement pas beaucoup, il vous donnera probablement un bloc d'une taille "standard", par exemple un bloc 2^n bloc d'octets. Par conséquent, la taille réelle (c'est-à-dire le nombre d'objets réellement alloués) est en fait inconnue.

Deuxièmement : le "petit plus" requis

En effet, l'information nécessaire pour qu'un objet donné sache s'il fait partie d'un tableau ou non serait simplement un bit supplémentaire. Logiquement.

En ce qui concerne la mise en œuvre : où placer ce bit ?

La mémoire allouée à l'objet lui-même ne devrait probablement pas être touchée, car c'est l'objet qui l'utilise après tout. Alors ?

  • sur certaines plates-formes, cela pourrait être conservé dans le pointeur lui-même (certaines plates-formes ignorent une partie des bits), mais ce n'est pas portable
  • Cela nécessiterait donc un stockage supplémentaire, d'au moins un octet, sauf qu'en cas de problèmes d'alignement, il pourrait bien s'agir de 8 octets.

Démonstration : (pas convaincant comme noté par qqch, voir ci-dessous)

// A plain array of doubles:
+-------+-------+-------
|   0   |   1   |   2   
+-------+-------+-------

// A tentative to stash our extra bit
+-------++-------++-------++
|   0   ||   1   ||   2   ||
+-------++-------++-------++

// A correction since we introduced alignment issues
// Note: double's aligment is most probably its own size
+-------+-------+-------+-------+-------+-------
|   0   |  bit  |   1   |  bit  |   2   |  bit
+-------+-------+-------+-------+-------+-------

Humpf !

EDIT

Par conséquent, sur la plupart des plates-formes (où l'adresse compte), vous devrez "étendre" chaque pointeur et doubler leur taille (problèmes d'alignement).

Est-il acceptable que tous les pointeurs soient deux fois plus grands uniquement pour que vous puissiez cacher ce bit supplémentaire ? Pour la plupart des gens, je suppose que oui. Mais le C++ n'est pas conçu pour la plupart des gens, il est principalement conçu pour les personnes qui se soucient des performances, que ce soit la vitesse ou la mémoire, et en tant que tel, ce n'est pas acceptable.

FIN DE L'EDIT

Quelle est donc la bonne réponse ? La bonne réponse est que la récupération des informations perdues par le système de typographie est coûteuse. Malheureusement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X