J'essaie d'implémenter un tableau créé dynamiquement en utilisant new
que je veux redimensionner mais l'action de redimensionnement ne fonctionne pas correctement.
Ceci est un exercice sur les tableaux dynamiques, j'ai donc besoin de tableaux dynamiques utilisant new
et non std::vector
.
Voici mon code:
int main () { // Build an application here int length = 0; int size = 0; int input; bool endAdding = false; cout << "Please enter the length of the new array : "; cin >> length; int* oPtrDynamicArray = CreateDynamicArray (length, size); do { cout << "Add an element (0 to quit) : " << endl; cin >> input; cout << endl << endl; if (input == 0){ endAdding = true; } else { InsertElement(oPtrDynamicArray, input, size, length); } cout << "The array contains : " << endl; for (int i = 0; i < size; i++) { cout << i << ": [" << oPtrDynamicArray[i] << "]" << endl; } } while (!endAdding); DeleteDynamicArray (oPtrDynamicArray, size); } int *CreateDynamicArray (int capacity, int &size) { size = 0; return new int[capacity]; } void DeleteDynamicArray (int *dynamicArray, int &size) { delete[] dynamicArray; dynamicArray = nullptr; size = 0; } void InsertElement (int *dynamicArray, int element, int &size, int capacity) { if (capacity <= size) { ResizeDynamicArray (&dynamicArray, size+1); } dynamicArray[size] = element; size++; } void ResizeDynamicArray (int **dynamicArray, int newCapacity) { int ** newArray = new int*[newCapacity]; for (int i = 0; i < newCapacity; i++) { newArray[i] = dynamicArray[i]; } *dynamicArray = *newArray; delete[] newArray; newArray = nullptr; }
Le problème est que le tableau est passé à ma fonction InsertElement()
puis à ResizeDynamicArray()
uniquement si la capacity <= size
, mais le tableau passé à la première fonction, est passé avec de bonnes valeurs, mais avec des pointeurs anormaux dans le tableau.
Exemple :
Pour un tableau de 3, j'ai:
tableau [0] = 1 -> adresse 0x0004e300 contenant la valeur 1
tableau [1] = 2 -> adresse 0x00000003 contenant ???
array [2] = 3 -> adresse 0x008ffb24 contenant la valeur 2
Je ne comprends vraiment pas, ce serait vraiment génial si quelqu'un pouvait expliquer mon erreur: /.
3 Réponses :
Le problème est là
void ResizeDynamicArray (int **dynamicArray, int newCapacity) { int * newArray = new int[newCapacity]; for (int i = 0; i < newCapacity; i++) { newArray[i] = (*dynamicArray)[i]; } delete[] *dynamicArray; *dynamicArray = newArray; }
lorsque vous appelez ResizeDynamicArray
vous modifiez le pointeur dynamicArray
déclaré en tant que paramètre à InsertElement
. Vous ne modifiez pas le pointeur oPtrDynamicArray
dans main.
Si vous voulez que cela fonctionne, vous devez modifier InsertElement
pour prendre un double pointeur (tout comme ResizeDynamicArray
)
void InsertElement (int **dynamicArray, int element, int &size, int capacity) { if (capacity <= size) { ResizeDynamicArray (dynamicArray, size+1); } (*dynamicArray)[size] = element; size++; }
Ou vous pouvez faire la chose facile et utiliser simplement std::vector<int>
.
EDIT maintenant que je regarde votre fonction ResizeDynamicArray
, je vois que cette fonction est également complètement fausse. Il est clair que vous avez appris à faire avec les pointeurs
Voici comment ResizeDynamicArray
devrait être
void InsertElement (int *dynamicArray, int element, int &size, int capacity) { if (capacity <= size) { ResizeDynamicArray (&dynamicArray, size+1); } dynamicArray[size] = element; size++; }
Vous n'êtes pas le premier débutant à ne pas comprendre les pointeurs. Jetez un œil au code ci-dessus et comparez-le avec votre code. La principale différence est que mon code utilise un pointeur pour changer ce qui est pointé . Votre code a essayé de modifier le pointeur lui-même, ce qui est incorrect. C'est déroutant car ce qui est pointé est un autre pointeur (le tableau dynamique).
Mmmmh J'ai essayé cela avant, mais cela ne fonctionnait pas parce que je ne savais pas que je pouvais attribuer une valeur comme celle-ci pour dynamicArray Merci, cela fonctionne maintenant, mais le problème est maintenant la fonction deleteArray, avec une exception "Heap Corruption Detected". J'ai vu que je devais faire de même, en passant par référence, alors je l'ai fait, mais ça ne marche pas du tout ...
C'est pourquoi je m'exerce spécifiquement sur les tableaux, je viens du développement web donc c'est super dur pour moi pointer ^^. Merci de votre aide ! :RÉ
Aaaaaaaaaaa et ça marche !! Merci pour votre aide, donc le gros problème était que je mélangeais entre les tableaux d'int, les tableaux de pointeur et le pointeur sur int -_-. J'ai encore besoin de beaucoup de pratique pour bien le comprendre.
Il y a plusieurs problèmes dans votre code:
Tout d'abord, dans ResizeDynamicArray
, vous ResizeDynamicArray
un tableau de pointeurs aux entiers, pas un tableau d'entiers. int ** newArray = new int*[newCapacity]
doit être int *newArray = new int[newCapacity]
.
Deuxièmement, une fois que vous avez corrigé cela, vous devez écrire *dynamicArray = newArray;
; mais vous devez libérer l'ancien tableau avant d'affecter le pointeur au nouveau bloc de mémoire.
void InsertElement (int **dynamicArray, int element, int &size, int capacity)
Troisièmement, puisque InsertElement
peut appeler ResizeDynamicArray
(qui vous rendra un nouveau bloc de mémoire), vous devez modifier le pointeur passé à l'origine. Vous devez donc passer un pointeur vers un pointeur dans la fonction, comme vous l'avez fait avec ResizeDynamicArray
:
void ResizeDynamicArray (int **dynamicArray, int newCapacity) { int *newArray = new int[newCapacity]; for (int i = 0; i < newCapacity; i++) { newArray[i] = (*dynamicArray)[i]; } delete[] *dynamicArray; *dynamicArray = newArray; }
adapter le corps en conséquence alors.
Mais comment fonctionne votre mission ?? Il me dit "La valeur de type int * ne peut pas être attribuée à une entité de type int" ?? J'allais comme ça, mais parce que je ne l'ai pas compris, j'ai changé la stratégie pour celle-ci (c'est évidemment faux grâce à votre explication: O)
Je sais que la question est déjà répondue mais pas le pourquoi.
Vous devez garder à l'esprit que les pointeurs sont passés aux fonctions par valeur . La valeur du pointeur, l'adresse vers laquelle il pointe , est perdue lorsque la fonction se termine. Mais vous pouvez toujours modifier la valeur stockée à l'adresse vers laquelle elle pointe en déréférençant le pointeur.
Pour réussir à changer la valeur du pointeur, l'adresse vers laquelle il pointe , à l'intérieur d'une fonction, vous devez passer un pointeur vers un pointeur. Dans ce cas, le passage d'un double pointeur est synonyme de passage d'un pointeur vers une fonction par référence .
void Foo(int **ptr) { // Don't use ptr, changes are lost after function end as ptr is a local copy // Use *ptr to change the value of the pointer you passed to the function. // Use **ptr to change the value at the address the pointer you passed to the funcion points to }
Dans ce cas, vous pouvez modifier la valeur du pointeur, l'adresse vers laquelle il pointe , en déréférençant une fois le double pointeur. Ce qui s'applique aux réponses ci-dessus.
Un std :: vector est un tableau dynamique.
Ce que vous décrivez est impossible. Votre "tableau dynamique" est un tableau simple de style C - qui se désintègre en
int *
que vous tenez. Ses éléments sont des entiers , pas des pointeurs , et ont des adresses consécutives (en multiples desizeof(int)
bien sûr) - ils ne peuvent pas avoir les adresses que vous avez répertoriées dans votre exemple.Je sais que c'est bien, mais pour mon exercice, je ne dois pas utiliser de vecteur: /
Et je ne comprends vraiment pas trop ces adresses, c'est mon débogueur qui me montre celles-ci: / Ce sont les références du "dynamicArray" dans "InsertElement ()" Mais cela crée un problème après, j'obtiens une exception à chaque fois au hasard sur resizedArray