Un conteneur STL de pointeur ne va PAS nettoyer les données de pointe. Il ne nettoie l'espace en tenant le pointeur. Si vous voulez le vecteur de nettoyer les données de pointeur vous avez besoin d'utiliser une sorte de pointeur intelligent de mise en œuvre:
Lors que le champ d'application se termine à la fois des vecteurs libres de leurs séries internes. v1 est une fuite de la SomeClass qui a été créé depuis seulement le pointeur est dans le tableau. v2 aura pas de fuite des données.
Si vous avez un vector<T*>, votre code doit supprimer les pointeurs avant de le supprimer avec le vecteur: sinon, que des fuites de mémoire.
Sais que C++ n'est pas de faire de la collecte des ordures, voici un exemple de pourquoi (appologies pour les erreurs de syntaxe, il a été un moment depuis que j'ai écrit en C++):
La dernière ligne (delete vt1;) clairement ne devez pas supprimer le pointeur qu'il contient; après tout, c'est aussi dans vt2. Donc il n'a pas. Ni le supprimer de vt2.
(Si vous voulez un type de vecteur qui supprime les pointeurs sur les détruire, ce type de cours peut être écrite. A probablement été. Mais méfiez-vous de supprimer avec les pointeurs que quelqu'un d'autre tient toujours une copie.)
Oui, il a: boost::ptr_vector. (voir boost ptr conteneurs)
C'est un peu un abus de langage. Un vecteur, comme avec la plupart des conteneurs STL, se compose de 2 parties logiques.
l'occurrence de vector
le sous-jacent de la matrice de mise en œuvre
Tout configurable, no 2 presque toujours de la vie sur le tas. #1 mais peuvent vivre sur la pile ou le tas, ça dépend comment il est alloué. Par exemple
void foo(){
vector<int> v;
v.push_back(42);}
Dans ce cas, la partie #1 vie sur la pile.
Maintenant comment #2 de la destruction? Lors de la première partie d'un vecteur est détruit, il va détruire la deuxième partie. Ceci est fait par la suppression du sous-jacent de tableau à l'intérieur du destructeur de la classe vector.
Si vous stocker des pointeurs dans le conteneur STL classes, vous devez les supprimer manuellement avant que l'objet est détruit. Cela peut être fait en parcourant l'ensemble du conteneur et la suppression de chaque élément, ou en utilisant une sorte de pointeur intelligent de la classe. Cependant, ne pas utiliser de auto_ptr comme cela ne fonctionne tout simplement pas avec les conteneurs à tous.
Un bon effet secondaire de ceci est que vous pouvez les garder plusieurs conteneurs de pointeurs dans votre programme, mais seulement ceux des objets appartenant à l'un de ces conteneurs, et vous avez seulement besoin de les nettoyer qu'un conteneur.
La façon la plus simple de supprimer les pointeurs serait de faire:
for(ContainerType::iterator it(container.begin()); it != container.end();++it){delete(*it);}
Ce n'est pas conseillé (à moins de faire partie de l'destructeur), car il n'est pas une exception coffre-fort. Vous devez utiliser un récipient qui comprend qui est de la tenue d'un pointeur. Comment est-il pas exception sûr? Si ContainerType est quelque chose comme std::vector<std::string> par exemple, alors c'est parfaitement valide le code à mettre dans un destructeur et un "clair" ou "reset" comme méthode.
Utiliser des pointeurs intelligents à l'intérieur du vecteur, ou de l'utilisation de boost ptr_vector. Il va automatiquement libérer les objets alloués à l'intérieur. Il y a aussi des cartes, jeux, etc.
Il n'y a rien de spécial à propos de STL classes (je l'espère). Ils fonctionnent exactement comme les autres classes de modèle. Ainsi, ils ne sont pas automatiquement détruits si alloué sur le tas, parce que le C++ n'a pas de collecte des ordures sur eux (sauf si vous lui dites avec une certaine fantaisie autoptr d'affaires ou de quelque chose). Si vous allouer sur la pile (sans nouvelles) il sera probablement géré par le C++ automatiquement.
Pour votre deuxième question, voici une très simple ArrayOfTen classe pour démontrer les principes de base typiques de la gestion de la mémoire en C++:
/* Holds ten Objects. */classArrayOfTen{public:ArrayOfTen(){
m_data =newObject[10];}~ArrayOfTen(){delete[] m_data;}Object&operator[](int index){/* TODO Range checking */return m_data[index];}private:Object*m_data;ArrayOfTen&operator=(constArrayOfTen&){}};ArrayOfTen myArray;
myArray[0]=Object("hello world");//bleh
Fondamentalement, la ArrayOfTen classe conserve un tableau interne de dix éléments Objet sur le tas. Lorsque[] est appelée dans le constructeur, en l'espace de dix Objets est alloué sur le tas, et dix Objets sont construits. Simiarly quand delete[] est appelé dans le destructeur, les dix Objets sont déconstruits et puis la mémoire précédemment allouée est libéré.
Pour la plupart (tous?) Types STL, le redimensionnement est effectué en coulisse pour s'assurer qu'il y a assez de mémoire asside pour s'adapter à vos éléments. La classe ci-dessus prend uniquement en charge les tableaux de dix Objets. En gros, c'est un très limitant la définition de type de l'Objet[10].
Le standard des conteneurs STL place une copie de l'objet original dans le récipient, à l'aide du constructeur de copie. Lorsque le conteneur est détruit, le destructeur de chaque objet dans le conteneur est également appelé à détruire de façon sécuritaire l'objet.
Les pointeurs sont traitées de la même manière.
Le truc, c'est les pointeurs sont GOUSSE de données. Le constructeur de copie pour un pointeur, c'est juste pour copier l'adresse et la GOUSSE de données n'a pas de destructeur. Si vous souhaitez que le conteneur pour gérer un pointeur, vous devez:
Utiliser un récipient de pointeurs intelligents. (par exemple pointeur partagé).
Utiliser un coup de pouce ptr conteneur.
Je préfère le pointeur contenant:
Le pointeur de conteneurs sont les mêmes que les conteneurs STL à l'exception de vous mettre des pointeurs vers eux, mais le conteneur prend la propriété de l'objet que le pointeur de points et donc de libérer l'objet (généralement en appelant supprimer) lorsque le conteneur est détruit.
Lorsque vous accédez à des membres d'une ptr conteneur ils sont renvoyés via de référence de sorte qu'ils se comportent comme un conteneur standard pour une utilisation dans les algorithmes standards.
int main(){
boost::ptr_vector<int> data;
data.push_back(newint(5));
data.push_back(newint(6));
std::cout << data[0]<<"\n";//Prints 5.
std::cout << data[1]<<"\n";//Prints 6.}//data deallocated.//This will also de-allocate all pointers that it contains.//by calling delete on the pointers. Therefore this will not leak.
Il convient également de souligner que des pointeurs intelligents dans un conteneur est une alternative valable, malheureusement std::auto_ptr<> n'est pas un choix valide de pointeur intelligent pour cette situation.
C'est parce que les conteneurs STL supposer que les objets qu'elles contiennent sont copiable, malheureusement std::auto_ptr<> n'est pas copiable dans le sens traditionnel du terme, car elle détruit la valeur d'origine sur la copie et donc la source de la copie ne peut pas être const.
Conteneurs STL sont comme tous les autres objets, si vous instanciez un il est créé sur la pile:
std::vector<int> vec(10);
Juste comme n'importe quel autre pile de la variable, il ne vit que dans le domaine de la fonction est définie, et n'a pas besoin d'être supprimés manuellement. Le destructeur de conteneurs STL va appeler le destructeur de tous les éléments dans le conteneur.
Garder des pointeurs dans un conteneur est un risquée question. Puisque les pointeurs n'ont pas destructeurs, je dirais que vous ne voulez jamais à mettre raw pointeurs dans un conteneur STL. Ce faisant, une exception se produit de façon sécuritaire sera très difficile, vous auriez à litière de votre code avec un try{}finally{} blocs pour s'assurer que le contenu de l'pointeurs sont toujours libéré.
Alors, que devez-vous mettre dans des conteneurs au lieu de raw pointeurs? +1 jmucchiello pour l'éducation de boost::shared_ptr. boost::shared_ptr est sûr à utiliser dans des conteneurs STL (à la différence de std::auto_ptr). Il utilise un simple mécanisme de calcul de référence, et est sûr à utiliser pour les structures de données qui ne contiennent pas de cycles.
De quoi avez vous besoin pour les structures de données qui contiennent des cycles? Dans ce cas, vous voudrez probablement supérieures à la collecte des déchets, ce qui signifie essentiellement en utilisant un autre langage comme Java. Mais c'est un autre débat. 😉
Un conteneur STL de pointeur ne va PAS nettoyer les données de pointe. Il ne nettoie l'espace en tenant le pointeur. Si vous voulez le vecteur de nettoyer les données de pointeur vous avez besoin d'utiliser une sorte de pointeur intelligent de mise en œuvre:
Lors que le champ d'application se termine à la fois des vecteurs libres de leurs séries internes. v1 est une fuite de la SomeClass qui a été créé depuis seulement le pointeur est dans le tableau. v2 aura pas de fuite des données.
OriginalL'auteur jmucchiello
Si vous avez un
vector<T*>
, votre code doit supprimer les pointeurs avant de le supprimer avec le vecteur: sinon, que des fuites de mémoire.Sais que C++ n'est pas de faire de la collecte des ordures, voici un exemple de pourquoi (appologies pour les erreurs de syntaxe, il a été un moment depuis que j'ai écrit en C++):
La dernière ligne (
delete vt1;
) clairement ne devez pas supprimer le pointeur qu'il contient; après tout, c'est aussi dans vt2. Donc il n'a pas. Ni le supprimer devt2
.(Si vous voulez un type de vecteur qui supprime les pointeurs sur les détruire, ce type de cours peut être écrite. A probablement été. Mais méfiez-vous de supprimer avec les pointeurs que quelqu'un d'autre tient toujours une copie.)
OriginalL'auteur derobert
Lorsqu'un vecteur est hors de portée, le compilateur émet un appel à son destructeur, qui à son tour libère la mémoire allouée sur le tas.
OriginalL'auteur Mehrdad Afshari
C'est un peu un abus de langage. Un vecteur, comme avec la plupart des conteneurs STL, se compose de 2 parties logiques.
Tout configurable, no 2 presque toujours de la vie sur le tas. #1 mais peuvent vivre sur la pile ou le tas, ça dépend comment il est alloué. Par exemple
Dans ce cas, la partie #1 vie sur la pile.
Maintenant comment #2 de la destruction? Lors de la première partie d'un vecteur est détruit, il va détruire la deuxième partie. Ceci est fait par la suppression du sous-jacent de tableau à l'intérieur du destructeur de la classe vector.
OriginalL'auteur JaredPar
Si vous stocker des pointeurs dans le conteneur STL classes, vous devez les supprimer manuellement avant que l'objet est détruit. Cela peut être fait en parcourant l'ensemble du conteneur et la suppression de chaque élément, ou en utilisant une sorte de pointeur intelligent de la classe. Cependant, ne pas utiliser de auto_ptr comme cela ne fonctionne tout simplement pas avec les conteneurs à tous.
Un bon effet secondaire de ceci est que vous pouvez les garder plusieurs conteneurs de pointeurs dans votre programme, mais seulement ceux des objets appartenant à l'un de ces conteneurs, et vous avez seulement besoin de les nettoyer qu'un conteneur.
La façon la plus simple de supprimer les pointeurs serait de faire:
Comment est-il pas exception sûr? Si ContainerType est quelque chose comme std::vector<std::string> par exemple, alors c'est parfaitement valide le code à mettre dans un destructeur et un "clair" ou "reset" comme méthode.
OriginalL'auteur Daemin
Utiliser des pointeurs intelligents à l'intérieur du vecteur, ou de l'utilisation de boost ptr_vector. Il va automatiquement libérer les objets alloués à l'intérieur. Il y a aussi des cartes, jeux, etc.
http://www.boost.org/doc/libs/1_37_0/libs/ptr_container/doc/ptr_vector.html
et le site principal:
http://www.boost.org/doc/libs/1_37_0/libs/ptr_container/doc/ptr_container.html
OriginalL'auteur Michel
Comme avec n'importe quel autre objet dans le tas, il doit être détruit manuellement (à supprimer).
OriginalL'auteur zvrba
Pour répondre à votre première question:
Il n'y a rien de spécial à propos de STL classes (je l'espère). Ils fonctionnent exactement comme les autres classes de modèle. Ainsi, ils ne sont pas automatiquement détruits si alloué sur le tas, parce que le C++ n'a pas de collecte des ordures sur eux (sauf si vous lui dites avec une certaine fantaisie autoptr d'affaires ou de quelque chose). Si vous allouer sur la pile (sans nouvelles) il sera probablement géré par le C++ automatiquement.
Pour votre deuxième question, voici une très simple ArrayOfTen classe pour démontrer les principes de base typiques de la gestion de la mémoire en C++:
Fondamentalement, la ArrayOfTen classe conserve un tableau interne de dix éléments Objet sur le tas. Lorsque[] est appelée dans le constructeur, en l'espace de dix Objets est alloué sur le tas, et dix Objets sont construits. Simiarly quand delete[] est appelé dans le destructeur, les dix Objets sont déconstruits et puis la mémoire précédemment allouée est libéré.
Pour la plupart (tous?) Types STL, le redimensionnement est effectué en coulisse pour s'assurer qu'il y a assez de mémoire asside pour s'adapter à vos éléments. La classe ci-dessus prend uniquement en charge les tableaux de dix Objets. En gros, c'est un très limitant la définition de type de l'Objet[10].
OriginalL'auteur strager
Supprimer les éléments pointés, j'ai écrit un foncteur simple:
Mais vous devriez secours sur le partage des pointeurs lorsque le vecteur est le contenu doit être ... euh... partagé. Oui.
OriginalL'auteur xtofl
Un foncteur qui supprime les pointeurs de STL conteneurs de séquence
OriginalL'auteur Nemanja Trifunovic
Le standard des conteneurs STL place une copie de l'objet original dans le récipient, à l'aide du constructeur de copie. Lorsque le conteneur est détruit, le destructeur de chaque objet dans le conteneur est également appelé à détruire de façon sécuritaire l'objet.
Les pointeurs sont traitées de la même manière.
Le truc, c'est les pointeurs sont GOUSSE de données. Le constructeur de copie pour un pointeur, c'est juste pour copier l'adresse et la GOUSSE de données n'a pas de destructeur. Si vous souhaitez que le conteneur pour gérer un pointeur, vous devez:
Je préfère le pointeur contenant:
Le pointeur de conteneurs sont les mêmes que les conteneurs STL à l'exception de vous mettre des pointeurs vers eux, mais le conteneur prend la propriété de l'objet que le pointeur de points et donc de libérer l'objet (généralement en appelant supprimer) lorsque le conteneur est détruit.
Lorsque vous accédez à des membres d'une ptr conteneur ils sont renvoyés via de référence de sorte qu'ils se comportent comme un conteneur standard pour une utilisation dans les algorithmes standards.
Il convient également de souligner que des pointeurs intelligents dans un conteneur est une alternative valable, malheureusement std::auto_ptr<> n'est pas un choix valide de pointeur intelligent pour cette situation.
C'est parce que les conteneurs STL supposer que les objets qu'elles contiennent sont copiable, malheureusement std::auto_ptr<> n'est pas copiable dans le sens traditionnel du terme, car elle détruit la valeur d'origine sur la copie et donc la source de la copie ne peut pas être const.
OriginalL'auteur Martin York
Conteneurs STL sont comme tous les autres objets, si vous instanciez un il est créé sur la pile:
Juste comme n'importe quel autre pile de la variable, il ne vit que dans le domaine de la fonction est définie, et n'a pas besoin d'être supprimés manuellement. Le destructeur de conteneurs STL va appeler le destructeur de tous les éléments dans le conteneur.
Garder des pointeurs dans un conteneur est un risquée question. Puisque les pointeurs n'ont pas destructeurs, je dirais que vous ne voulez jamais à mettre raw pointeurs dans un conteneur STL. Ce faisant, une exception se produit de façon sécuritaire sera très difficile, vous auriez à litière de votre code avec un try{}finally{} blocs pour s'assurer que le contenu de l'pointeurs sont toujours libéré.
Alors, que devez-vous mettre dans des conteneurs au lieu de raw pointeurs? +1 jmucchiello pour l'éducation de boost::shared_ptr. boost::shared_ptr est sûr à utiliser dans des conteneurs STL (à la différence de std::auto_ptr). Il utilise un simple mécanisme de calcul de référence, et est sûr à utiliser pour les structures de données qui ne contiennent pas de cycles.
De quoi avez vous besoin pour les structures de données qui contiennent des cycles? Dans ce cas, vous voudrez probablement supérieures à la collecte des déchets, ce qui signifie essentiellement en utilisant un autre langage comme Java. Mais c'est un autre débat. 😉
OriginalL'auteur Anton I. Sipos