2010-10-29 25 views
2

Je suis un étudiant qui écrit une méthode qui supprime des zéros de la fin d'un tableau d'ints, en C++. Le tableau est dans une structure, et la structure a aussi un int qui garde une trace de la longueur du tableau.Est-il nécessaire de supprimer des éléments lors du rétrécissement d'un tableau?

La méthode examine chaque élément à partir de la dernière, jusqu'à ce qu'il rencontre le premier élément non nul, et marque celui-ci comme "dernier élément" en changeant la valeur de la longueur. Ensuite, la méthode revient au "dernier élément" d'origine, en supprimant les éléments qui ne sont pas hors limites (les zéros).

La partie qui supprime l'élément i e dans le tableau si i est supérieure à la longueur mise à jour du tableau, ressemble à ceci:

if (i > p->length - 1) { 
    delete (p->elems + i); // free ith elem 

Cette ligne ne va pas, cependant. Supprimer prend un pointeur, oui? Donc mon sentiment est que j'ai besoin de récupérer le pointeur sur le tableau, puis ajouter i pour que j'aurai l'emplacement de la mémoire de l'entier que je veux supprimer.

Est-ce que mon intuition est incorrecte? L'erreur est-elle subtile? Ou, ai-je la toute fausse idée? J'ai commencé à me demander: ai-je vraiment besoin de libérer ces primitifs? S'ils n'étaient pas primitifs, j'en aurais besoin, et dans ce cas, comment le ferais-je?

+1

pouvez vous montrer comment la struct ressemble et la déclaration de « p »? –

Répondre

3

Si p->elems est un pointeur, alors il en est p->elems + i (en supposant l'opération est définie, à savoir i est de type intégral) - et p->elems + i == &p->elems[i]

Quoi qu'il en soit, vous ne voulez probablement pas (et ne peut pas) supprimer ints d'un tableau de int (que ce soit dynamiquement ou automatiquement alloué). C'est

int* ptr = new int[10]; 
delete &ptr[5]; // WRONG! 

C'est simplement quelque chose que vous ne pouvez pas faire. Toutefois, si la structure contient la longueur du tableau, vous pouvez considérer le tableau "redimensionné" après avoir modifié les informations de longueur contenues dans la structure - après tout, il est impossible de déterminer la taille du tableau pointé par un pointeur. Si toutefois votre tableau est un tableau de pointeurs vers des entiers (int*[]) et que ces pointeurs pointent vers de la mémoire allouée dynamiquement, alors oui, vous pouvez supprimer des éléments simples et le faire le long des lignes de votre code (vous montrent si peu de code qu'il est difficile d'être exact).

5

Est-ce que j'ai eu l'idée complètement fausse?

J'ai bien peur.

Si vous faites un new[] appel à allouer un tableau, vous devez faire un delete[] appel à libérer:

int *p = new int[10]; 
... 
delete[] p; 

Si votre tableau est dans un struct, et vous faites un appel à affecter le struct , alors vous devez faire un appel pour le libérer:

struct Foo { 
    int data[10]; 
}; 

Foo *foo = new Foo; 
... 
delete foo; 

Il n'y a aucun moyen de libérer une partie d'un tableau.

Un tableau int[10] fait est 10 entiers, dans une rangée (soit 40 octets de mémoire sur un système 32 bits, les frais généraux peut-être plus).Les entiers valeurs qui sont stockés dans le tableau occupent cette mémoire - ils ne sont pas eux-mêmes des allocations de mémoire, et ils n'ont pas besoin d'être libérés.

Cela dit, si vous voulez un tableau de longueur variable:

c'est ce que std :: vecteur est pour

#include <vector> 
#include <iostream> 

struct Foo { 
    std::vector<int> vec; 
}; 

int main() { 
    Foo foo; 

    // no need for a separate length: the current length of the vector is 
    std::cout << foo.vec.size() << "\n"; 

    // change the size of the vector to 10 (fills with 0) 
    foo.vec.resize(10); 

    // change the size of the vector to 7, discarding the last 3 elements 
    foo.vec.resize(7); 
}