Pourquoi l’opérateur «delete … multiDimensionalArray;» en C ++ n’existe-t-il pas?

Je me demandais toujours s’il existe un opérateur pour supprimer des tableaux multidimensionnels dans le langage C ++ standard.

Si nous avons créé un pointeur sur un tableau à une dimension

int *array = new int[size]; 

la suppression ressemble à:

 delete [] array; 

C’est génial. Mais si nous avons un tableau à deux dimensions, nous ne pouvons pas faire

 delete [][] twoDimenstionalArray; 

Au lieu de cela, nous devrions boucler et supprimer les éléments, comme dans cet exemple.

Quelqu’un peut-il expliquer pourquoi?

Techniquement, il n’y a pas de tableaux à deux dimensions en C ++. Ce que vous utilisez comme tableau à deux dimensions est un tableau à une dimension, chaque élément étant un tableau à une dimension. Comme il n’existe pas techniquement, C ++ ne peut pas le supprimer.

Parce qu’il n’y a pas moyen d’appeler

 int **array = new int[dim1][dim2]; 

Toutes les nouvelles / suppressions doivent être équilibrées, un opérateur delete [][] n’a donc aucun intérêt.

new int[dim1][dim2] renvoie un pointeur sur un tableau de taille dim1 de type int[dim2] . Donc, dim2 doit être une constante de temps de compilation. Ceci est similaire à l’allocation de tableaux multidimensionnels sur la stack.

La raison pour laquelle delete est appelée plusieurs fois dans cet exemple est que new est également appelé plusieurs fois. Supprimer doit être appelé pour chaque nouveau.

Par exemple, si j’alloue 1 000 000 octets de mémoire, je ne peux pas supprimer ultérieurement les entrées comsockets entre 200 000 et 300 000. Elle a été allouée sous la forme d’un bloc entier et doit être libérée sous la forme d’un bloc entier.

La raison pour laquelle vous devez effectuer une boucle, comme dans l’exemple que vous avez mentionné, est que le nombre de tableaux à supprimer n’est pas connu du compilateur / allocateur.

Lorsque vous avez alloué votre tableau à deux dimensions, vous avez réellement créé N tableaux à une dimension. Chacun de ces éléments doit maintenant être supprimé, mais le système ne sait pas combien il en existe. La taille du tableau de niveau supérieur, c’est-à-dire le tableau de pointeurs des tableaux de second niveau, est identique à celle de tout autre tableau en C: sa taille n’est pas stockée par le système.

Par conséquent, il n’y a aucun moyen d’implémenter delete [][] comme vous le décrivez (sans changer la langue de manière significative).

pas sûr de la raison exacte du sharepoint vue de la conception du langage, je suppose que cela a quelque chose à voir avec le fait que lors de l’allocation de mémoire, vous créez un tableau de tableaux et que chacun d’eux doit être supprimé.

 int ** mArr = new int*[10]; for(int i=0;i<10;i++) { mArr[i]=new int[10]; } 

mon c ++ est rouillé, je ne sais pas si c'est syntaxiquement correct, mais je pense que c'est proche.

Bien que toutes ces réponses soient pertinentes, je vais essayer d’expliquer ce qui est venu à une attente, quelque chose comme une delete[][] array; peut travailler sur des tableaux alloués dynamicment et pourquoi ce n’est pas possible:

La syntaxe int array[ROWS][COLS]; autorisé sur les tableaux statiquement alloués n’est qu’une abstraction pour les programmeurs, qui crée en réalité un tableau unidimensionnel int array[ROWS*COLS]; . Mais pendant le processus de compilation (lorsque les tailles COLS et ROWS doivent être constantes), le compilateur se souvient également de la taille de ces dimensions, nécessaires pour adresser ultérieurement les éléments à l’aide de la syntaxe, par exemple array[x][y] = 45 . Le compilateur, étant connu de cette taille, remplacera alors [x][y] par l’index correspondant au tableau à une dimension en utilisant un calcul simple: [COLS*x + y] .

Par contre, ce n’est pas le cas avec les tableaux alloués dynamicment , si vous voulez la même fonctionnalité multidimensionnelle (en fait la notation). Etant donné que leur taille peut être déterminée au moment de l’exécution, ils doivent également garder en mémoire la taille de chaque dimension supplémentaire pour une utilisation ultérieure – et ne l’oubliez pas pour toute la durée de vie du tableau. De plus, il faudrait implémenter ici des modifications du système pour pouvoir utiliser des tableaux multidimensionnels, laissant la forme de la notation d’access [x][y] dans le code, sans la remplacer par une notation unidimensionnelle lors de la compilation, mais plus tard. le remplacer au moment de l’exécution.

Par conséquent, l’ absence de array = new int[ROWS][COLS] n’implique aucune nécessité pour delete[][] array; . Et comme déjà mentionné, il ne peut pas être utilisé dans votre exemple pour supprimer votre tableau “multidimensionnel”, car vos sous-tableaux (dimensions supplémentaires) sont alloués séparément (en utilisant un new appel séparé), de sorte qu’ils sont indépendants du haut. array ( array_2D ) qui les contient et qui ne peuvent pas tous être supprimés en même temps.

delete [] s’applique à tout tableau non scalaire.

Vous pouvez utiliser une classe wrapper pour faire toutes ces choses pour vous. Travailler avec des types de données “primitifs” n’est généralement pas une bonne solution (les tableaux doivent être encapsulés dans une classe). Par exemple, std :: vector est un très bon exemple pour cela.

Supprimer doit être appelé exactement combien de fois nouveau est appelé. Comme vous ne pouvez pas appeler “a = new X [a] [b]”, vous ne pouvez pas également appeler “delete [] [] a”.

Techniquement, c’est une bonne décision de conception qui empêche l’apparition d’initialisations étranges d’une masortingce n-dimensionnelle entière.

Eh bien, je pense que c’est facile à mettre en œuvre, mais trop dangereux. Il est facile de dire si un pointeur est créé par new[] , mais difficile de dire à propos de new[]...[] (si autorisé).