Question

Exemple simple:

template <class P> class MyT
{
    struct Item
    {
    public:
        Item() {}
        P *pData;
        Item *next;
    };
    Item *head;
public:
    ...adding etc..
    P* operator [](int index)
    {
       See question below:
    }
};

Puis-je faire en quelque sorte assurer que les « années d'article sont attribués à façon telle que je puisse calculer le décalage comme suit: (Peut-être pas :) @ Steve si clair ici; ce que j'ai besoin est un moyen rapide et facile d'accès à l'élément sans Itère 10000 Prochaines étapes.

Item *pi = head + (sizeof(Item) * (index - 1));

(plus clair?) explication de ce que je veux dire

Était-ce utile?

La solution

Cela dépend ce que vous entendez par "etc", en "ajoutant, etc".

Si « etc » comprend « la suppression », alors vous avez le problème évident que si vous supprimez quelque chose au milieu de votre liste, puis de maintenir l'indexation, vous devez tout changement après vers le bas, ce qui signifie la mise à jour toutes les pointeurs next.

Je pense que peut-être vous avez simplifié votre exemple trop loin. Si vous avez besoin de stockage contigu, utilisez un vecteur (soit de P ou de Item s'il y a quelque chose d'utile dans Item que vous avez retiré). Si vous avez le stockage contigu, alors il n'y a aucun avantage à avoir un pointeur next, puisque vous pouvez simplement le calculer dans Item, en ajoutant 1 à this (contrôle alors obligé de vous assurer que vous ne l'avez pas atteint la fin).

Si vous avez besoin absolument le champ pointeur de la next publique, parce qu'elle fait partie d'une certaine interface que vous la mise en œuvre que vous ne pouvez pas changer, vous pouvez alors le mettre à jour dans le constructeur de copie et operator= pour Item, et l'interface a mieux interdire les clients de l'écriture à lui.

Il n'y a aucun moyen de dire la allocateur de mémoire pour allouer de la mémoire contiguë pour les allocations distinctes, si c'est ce que vous demandez. Comment cela fonctionnerait-il de même? Que faire si quand vous venez d'attribuer, l'adresse « suivante » est déjà occupée? Que faire si l'allocateur impose certains frais généraux, pour ses propres structures de contrôle (comme presque tous les allocataires à usage général ne), de sorte que l'attribution d'un Item nécessite plus de sizeof(Item) octets? Vous pouvez obtenir le comportement que vous voulez pendant un certain temps avec un allocateur de taille fixe , mais finalement il a besoin d'un nouveau bloc, ou vous supprimez quelque chose, et la relation ne tient plus.

Autres conseils

Je suppose que ce que vous avez besoin est un std :: liste ou std :: vecteur.

Mais ce que vous essayez fonctionnerait si vous avez alloué la mémoire séquentielle des articles et la tête pointe vers le début ainsi que la modification proposée par Yossarian.

Vous pouvez pré-allouer lors de l'initialisation si cette limite est franchie, allouer plus et copier le contenu de votre à cette zone, libérant ainsi l'existant.

Remarque:. Toutes ces choses sont enveloppées pour vous dans les conteneurs std

« Les limites de la mémoire » peuvent être contraints par des mots-clés spéciaux gcc

http://gcc.gnu.org/onlinedocs /gcc/Variable-Attributes.html#Variable-Attributes

regard sur "l'alignement"

Si je comprends bien votre question, vous devez remplacer operator new pour Item et ont l'allocateur pré-allouer suffisamment de mémoire pour stocker tous les Items dont vous aurez besoin (ce qui est impossible dans le cas général, mais peut être possible dans votre scénario spécifique). Ensuite, chaque fois qu'un Item est newed l'allocateur retourne l'emplacement suivant dans le bloc pré-alloué.

Tous ces regards non réaliste et la solution simple serait d'utiliser std::vector.

Item* pi = (head + (index - 1));

fait le travail. BTW, êtes-vous sûr que vous voulez faire? ressemble struct Item comme structure liste chaînée (contient next).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top