2009-06-22 6 views
1

J'ai du mal à comprendre le peu de code suivant que j'espérais créer un tableau sur le tas et le remplir avec les caractères 9 jusqu'à 0 (je sais que je pourrais index juste le tableau comme un tableau de pile normale avec [] notation à faire cela, mais je le fais de cette façon d'essayer de comprendre les pointeurs plus en profondeur):Création de tableaux sur le tas et adressage avec des pointeurs

int *ptrHeapArray = new int[10]; 

    for(int f=9; f>=0 ;f--) 
    { 
     *ptrHeapArray = f; 
     ptrHeapArray++; 
    } 
    for(int f=0; f<10; f++) 
     cout << ptrHeapArray[f] << "\n"; 

il imprime des valeurs compleletly inattendues. Comme je comprends ce qui précède, la commande 'new' crée un tableau sur le tas et m'envoie un pointeur vers l'adresse où se trouve le tableau. Puisque le pointeur que j'affecte (ptrHeapArray) est de taille int, j'ai supposé que je pourrais utiliser l'incrémentation de post de pointeur pour naviguer dans le tableau. Cependant, les résultats indiquent que mes hypothèses sont fausses. Cela m'a amené à penser que peut-être le pointeur renvoyé par le mot clé 'new' est juste un pointeur sur le tableau entier et ne peut pas être utilisé pour parcourir le tableau pour une raison quelconque. J'ai donc essayé de créer un autre pointeur vers le pointeur renvoyé par le « nouveau » mot-clé et utilisé que pour faire ma population tableau:

int *ptrHeapArray = new int[10]; //array to hold FRANK data in 32 bit chunks 
int *ptrToHeapArrayPointer = ptrHeapArray; 

for(int f=9; f>=0 ;f--) 
{ 
    *ptrToHeapArrayPointer = f; 
    ptrToHeapArrayPointer++; 
} 
for(int f=0; f<10; f++) 
    cout << ptrHeapArray[f] << "\n"; 

Cela a bien fonctionné. Quelqu'un peut-il m'expliquer pourquoi je devais faire cela et ne pas avoir utilisé le pointeur que le mot-clé 'new' m'a transmis?

Merci

Répondre

6

La ligne

ptrHeapArray++; 

dans votre première boucle incrémente le pointeur, de telle sorte qu'il ne pointe pas au début du tableau plus.

La ligne

int *ptrHeapArray = new int[10]; 

alloue la mémoire pour 10 des nombres entiers et des points ptrHeapArray au début de ce mémoire. Dans votre boucle for, vous déplacez ce pointeur. Lorsque ptrHeapArray pointe vers le troisième des entiers:

[0] [1] [2] [3] [4] 
^  ^ ^
orig. |  | 
     |  +-- ptrHeapArray[2] 
     | 
     +-- ptrHeapArray now points here 

puis ptrHeapArray [2] vous donnerait l'entier à la position 4. numéroté avec réservation initiale

+0

Il fondamentalement clobbers la tête de votre tableau –

+4

@Nathan: ne pas le mettre de cette façon. Vous ne faites pas de distinction entre le pointeur et ce qu'il pointe vers. C'est une distinction que les nouveaux programmeurs trouvent souvent difficile. "La tête du tableau" n'est pas tabassée (écrasée) du tout. C'est inchangé. Il n'y a plus de pointeur. – MSalters

4

Vous modifiez le pointeur dans le code. Après la première boucle du premier extrait, le pointeur pointe vers la fin du tableau plutôt que vers le début. Pour rendre les choses plus claires, cela fonctionnerait aussi (pas suggéré, mais démontre le comportement):

int *ptrHeapArray = new int[10]; 

for(int f=9; f>=0 ;f--) 
{ 
    *ptrHeapArray = f; 
    ptrHeapArray++; 
} 

ptrHeapArray -= 10; // reset the pointer to its original location 

for(int f=0; f<10; f++) 
    cout << ptrHeapArray[f] << "\n"; 
0

Lorsque vous ptrHeapArray ++ il inscrements ptrHeapArray. Lorsque vous venez d'imprimer les données, ptrHeapArray ne pointe plus au début du tableau.

0

Le problème est que dans votre premier exemple, ptrHeapArray est initialement défini au début du tableau. Lorsque vous parcourez votre boucle, vous incrémentez le pointeur et, à la fin de la boucle for, vous pointez sur le dernier élément du tableau. Lorsque vous parcourez la boucle for pour afficher toutes vos valeurs, vous indexez les valeurs après la fin du tableau, car ptrHeapArray pointe vers le dernier élément du tableau que vous avez attribué.

Il est également important de garder à l'esprit que vous devez vous assurer de ne pas perdre le pointeur d'origine que vous avez récupéré en utilisant le nouvel opérateur afin de pouvoir libérer la mémoire allouée sur le tas.

1

Votre ptrToHeapArrayPointer est mal nommé, il s'agit juste d'un int ptr standard que vous avez pointé au même endroit que ptrHeapArray. Si vous l'avez renommé currentPositionPtr, votre code pourrait avoir plus de sens pour vous.

0

Dans la première boucle, vous avez incrémenté votre pointeur ptrHeapArray jusqu'à la fin du tableau. Donc, après l'exécution de la première boucle for votre pointeur pointe vers la fin du tableau et non au début. Par conséquent, lorsque vous essayez d'imprimer le contenu du tableau, vous accédez à des allocations de mémoire non valides et le comportement est inattendu. Dans le second cas, vous prenez une copie de votre adresse de départ avant d'attribuer des valeurs au tableau. Ainsi, lorsque vous essayez d'imprimer le contenu en utilisant la copie, il pointera vers le début du tableau.

Questions connexes