2010-09-16 25 views
0

Je veux faire un programme qui laisse dire représente une matrice maintenant la matrice sera représentée par un vecteur que chaque objet dans le vecteur représentera un exemple de cellule: vecteur maintenant Lors de la construction de la matrice, le constructeur reçoit une liste de cellules à insérer dans la matrice. La taille de la liste est inconnue au moment de la compilationCréation d'objets en C++ ne pas utiliser "nouveau"

Je suis intéressé par la création de cette matrice sans utiliser de mémoire sur le tas. En d'autres termes, ne pas créer d'objet en utilisant le mot "nouveau" ou "supprimer" est-il possible de le faire si je ne sais pas combien d'objets sont destinés à être insérés dans le vecteur?

+11

_Pourquoi êtes-vous opposé à l'affectation de cet objet sur le tas? C'est à cela que sert le tas (enfin, l'une des choses principales, au moins). –

+0

Pourquoi pensez-vous que c'est une bonne idée d'éviter le tas? Que faire si la matrice est très grande et non clairsemée, ne pouvant donc pas s'adapter à la pile? –

+0

Sauf si vous avez une raison très spécifique pour éviter de «nouveau» cela ressemble à une idée de baaaad. –

Répondre

1

Il n'existe aucun moyen standard de procéder ainsi sans effectuer une manipulation directe (et donc dépendante de la plate-forme) du cadre de pile du programme/de la fonction en utilisant des instructions d'assemblage que je déconseillerais vivement. Qu'est-ce qui vous empêche d'utiliser le tas?

1

Utilisez alloca pour obtenir un pointeur, puis utilisez le en place new opérateur:

void *p = alloca(sizeof(Class)); 
new (p) Whatever(arguments); 

Cependant, ne lire la page de manuel alloca avant de l'utiliser! Soyez très prudent. Comme le dit Jim Brissom, alloca n'est pas portable.

Vous n'avez pas besoin de delete. La mémoire sera libérée lorsque la fonction retournera

+4

alloca n'est pas exactement portable ... –

+0

Envelopper cette gestion des ressources. Faire de la gestion de la mémoire à la main == mauvais. – GManNickG

+0

Problèmes de portabilité mis à part, est-ce que le pointeur renvoyé par 'alloca' est correctement aligné pour' Whatever'? –

1

Il y a un moyen, c'est très limitatif et très peu orthodoxe. Vous devez créer un tableau de taille statique de unsigned char qui forme un pool de mémoire. Il y aura une limite à la taille de la liste des objets. Vous devrez surcharger un opérateur new (et un opérateur delete) pour que cette classe cible spécifiquement un tel pool de mémoire. Cela dit, il n'y a vraiment aucune bonne raison d'aller dans cette direction.

+0

IIRC, placement nouveau que vous décrivez est assez commun dans l'imprimante Windows DDK. – mkb

+0

En fait, je pense que c'est la bonne façon de mettre un objet sur le tas à un endroit où il ne peut pas être paginé, si c'est absolument nécessaire. – mkb

1

Eh bien, si vous ne voulez pas utiliser la mémoire sur le tas, d'où voulez-vous l'obtenir? A) dépendant du système - vous pouvez demander au système d'exploitation d'allouer de la mémoire pour vous. Mais c'est un mauvais style (dépendant du système), et utilisera la même RAM ... juste d'une manière différente allouée. Par exemple, :: GlobalAlloc ou :: LocalAlloc dans Windows 32 fera de telles choses si vous êtes vraiment intéressé à le faire. B) les fichiers mappés en mémoire - cela peut être intéressant si vous le demandez car vous pensez que vous n'avez pas assez de RAM disponible et que le temps d'accès n'est pas un problème. C) avoir recours à des fonctions C comme malloc/free et lancer les pointeurs ... qui récupèrent la mémoire du tas, en évitant simplement les mots-clés "new" et "delete".

Cependant, il est difficile de dire quelle "bonne" solution sans information pourquoi vous voulez éviter de nouveaux/supprimer. Vous avez besoin d'allocation de mémoire dynamique, ces deux sont les outils pour le faire.

Pourriez-vous expliquer/reformuler votre question afin que vous puissiez obtenir des réponses plus précises?

2

Il existe une manière spéciale d'utiliser new pour allouer de la mémoire dans la pile ou comme stockage statique en utilisant ce qu'on appelle l'opérateur placement new. Avec cette version de new, vous réservez un morceau de mémoire et vous explicitement dire où vous voulez stocker une variable spécifique. Il fonctionnerait comme suit:

#include <new> 
    int main() 
    { 
     char buffer[500]; // chunk of memory 
     int p*; 
     p = new (buffer) int[10]; 
    } 

Notez que vous devez inclure le nouvel en-tête afin d'utiliser ce nouvel opérateur spécial. Dans ce cas, lorsque vous utilisez le stockage automatique, la mémoire sera libérée en quittant le bloc dans lequel il a été déclaré (le principal).

Références: C++ Primer plus. Chapitre 9. Page 420

+0

'buffer' n'est pas garanti pour être correctement aligné avec' int'. –

+0

Merci pour le conseil. C'était étrange de voir cet exemple dans le livre :) – Vintharas

+1

Mais cela utilise le mot 'nouveau'. L'OP ne veut pas de «nouveauté» ou de «suppression». Pas downvoting pour le moment! – Chubsdad