2014-06-20 3 views
0

Je pense à rendre la structure de données vectorielles plus efficace. Supposons que pour un type de données générique T ... alors que nous ajoutons un nouvel élément au vecteur, le vecteur std :: actuel consiste à réallouer un nouveau bloc de mémoire de n + 1 éléments.Rendre un vecteur plus efficace tout en ajoutant des éléments

Ce que je veux faire ...

j'ai écrit un petit programme:

#include<iostream> 

using namespace std; 

int main() 
{ 

    int *i,*j; 
    i=new int; 
    cout<<i; 
    delete i; 
    j=new int ; 
    cout<<j; 
    delete j; 

     return 0; 
} 

Les deux emplacements mémoire sont les mêmes ...

maintenant Ce que je pense est que le premier je vais allouer de la mémoire pour le type de données génériques comme ceci:

T *temp=new T; 

maintenant adresse mémoire de temp à l'adresse du dernier élément du vecteur .... Si elles diffèrent par sizeof (T) alors je vais ajouter le nouvel élément lui-même .... sinon le faire de la manière std::vector le fait ....

Donc, il réduit le coût de la copie de tous les éléments ... si les données sont volumineuses, cela peut faire une différence significative ...... !!

Pls me dire si je suis sur la bonne voie ...

+3

Les vecteurs ne peuvent pas faire ce que vous décrivez parce que cela provoquerait que 'push_back' ne remplisse pas sa complexité de temps constant amorti. Les vecteurs sont très efficaces, en particulier avec C++ 11, où les éléments peuvent être déplacés au lieu d'être copiés lorsqu'une réallocation se produit. De plus, vos astuces d'adresse mémoire ne sont en aucun cas garanties, donc non, cela ne fonctionnera pas du tout. – chris

+3

['std :: vector :: reserve'] (http://fr.cppreference.com/w/cpp/container/vector/reserve) – BoBTFish

+0

Non ... j'ai essayé ceci avec ma propre implémentation de vecteur .. L'opération de suppression sera de complexité temps constante ... ce que je fais est, seulement s'il y a assez d'espace adjacent au dernier élément du vecteur, je dis de ne pas copier tout le matériel à un diff. emplacement, mais pour l'affecter à côté du dernier élément lui-même .... – PRP

Répondre

2

Je comprends votre idée

Si new me donne de nouveau une adresse qui est contiguë à la mémoire déjà détenue par le MyVector objet, je vais juste l'utiliser sans réaffecter.

Oui, cela pourrait en effet fonctionner en théorie. Cependant, en pratique, il est impossible d'obtenir une telle adresse contiguë, car l'allocateur stockera probablement certaines données internes au début du bloc alloué (comme sa taille, ou un pointeur vers le bloc suivant, ou autre).

Les détails exacts dépendent de l'allocateur utilisé par votre bibliothèque standard (et tout le système d'exploitation), mais voici un exemple de comportement typique. Vous appelez new Tsizeof(T) est 16 (par exemple). operator new appelle malloc en interne, ce qui appelle la fonction d'allocation de votre système d'exploitation. Cette fonction alloue 20 octets de mémoire à l'adresse X. Il stocke «16» dans les 4 premiers octets à X et renvoie l'adresse X + 4 à malloc, qui à son tour le renvoie à operator new et cela à votre application. Il n'y a donc aucun moyen d'avoir une mémoire contiguë.

+0

yeahhh .... j'avais lu au sujet de malloc fonctionnant ... vous avez raison ... !! Dint croise mon esprit tout en pensant à une idée si folle ... réponse sera acceptée ... – PRP

+0

Une idée de plus croisée Mon esprit .... j'ai fait quelques expériences avec la façon dont malloc alloue la mémoire ... le code ci-dessus je avoir écrit va vérifier si la mémoire est disponible ou non .... maintenant si la mémoire est disponible alors ... ce que je vais faire est d'aller à la mémoire où malloc stocke ses "méta-données" et de le modifier afin qu'il pense qu'il avait alloué plus de mémoire qu'il n'en a réellement fait ..... et que le vecteur efficace peut être implémenté .... – PRP

+0

@PRP Et si ce "plus de mémoire" que vous revendiquez fictivement est déjà pris par quelque chose? De plus, votre code sera étroitement lié à l'implémentation particulière de 'malloc' sur laquelle vous faites cela. Et de toute façon, la complexité dans les petits cas n'a pas d'importance. Et la complexité des grands cas dans 'std :: vector' est déjà amortie constante. Est-ce si mauvais pour votre cas? – Angew

Questions connexes