7
votes

C et C ++: libérer une partie d'un pointeur alloué

Disons que j'ai un pointeur alloué à contenir 4096 octets. Comment utiliserait-il les 1024 derniers octets en C? Qu'en est-il de C ++? Et si, à la place, je voulais annoncer les premier 1024 octets et garder le reste (dans les deux langues)? Qu'en est-il de négociation du milieu (il me semble que cela nécessiterait de la diviser en deux pointeurs, avant et après la région de distribution).


3 commentaires

Pas sûr de cela, mais en utilisant un pointeur "faux" avec une taille de bonne taille, la suppression ou la libération de celui que vous souhaitez faire le tour, besoin d'au moins 2 pointeurs.


@claferri. C'est un comportement indéfini. Vous ne pouvez que libérer () des pointeurs renvoyés de Malloc / Realloc - sinon, comment est libre () savoir à quel point libre?


@RODDY: oupe tu as raison :)


6 Réponses :


1
votes

Vous pouvez le rendre plus court avec REALLOC (). Je ne pense pas que le reste est possible.


0 commentaires

3
votes

Si vous avez n octets de malloc Mémoire de vente, vous pouvez realloc m octets (où M << code> n ) et jetez ainsi le dernier nm octets.

à jeter du début, vous pouvez masloc un nouveau, plus petit tampon et memcpy les octets que vous voulez, puis gratuit l'original .

La dernière option est également disponible à l'aide de C ++ Nouveau et Supprimer . Il peut également imiter le premier realloc .


4 commentaires

"MALLOC / MEMCY / GRATUIT" est la manière dont la ré-liste peut être mise en œuvre en interne.


Je conviens que Realloc retournera généralement la (même) première partie, mais est-ce une exigence officielle pour Realloc? Je pense que cela pourrait être des implémentations pouvant déplacer les données vers un nouveau lieu.


Imaginez un schéma de réaffectation intelligent dans lequel le schéma historique des allocations est suivi ... S'il y avait eu des demandes de répartition récentes pour 4096 octets, il serait peut-être préférable de déplacer le bloc de rétrécissement ailleurs pour libérer ce bloc de 4k. Auquel cas l'adresse changera. Et Realloc renvoie un pointeur sur la nouvelle zone de mémoire. Le programmeur doit donc l'utiliser. Que ce soit change ou non.


Une autre façon de jeter le début serait d'utiliser memmove () pour déplacer les données, puis realloc () à la taille requise



1
votes

Vous pouvez utiliser realloc () pour rendre apparemment la mémoire plus courte. Notez que, pour certaines implémentations, un tel appel ne fera rien. Vous ne pouvez pas libérer le premier bit du bloc et conserver le dernier bit.

Si vous avez besoin de ce type de fonctionnalité, vous devez envisager d'utiliser une structure de données plus complexe. Un tableau n'est pas la bonne réponse à chaque problème de programmation.


1 commentaires

Je suis en train de mettre en œuvre un système de mémoire, donc je cherche à obtenir un accès aussi bas que possible tout en restant portable.



1
votes

http://fr.wikipedia.org/wiki/new_ ( C% 2b% 2b)

Résumé: Contrairement à C ''s Realloc, il n'est pas possible de réaffecter directement mémoire allouée avec nouveau []. Étendre ou réduire la taille d'un bloc, un doit allouer un nouveau bloc de suffisance taille, copie sur l'ancienne mémoire et Supprimer l'ancien bloc. La norme C ++ la bibliothèque fournit une matrice dynamique qui peut être étendu ou réduit dans sa Std :: Modèle Vecteur.


0 commentaires

12
votes

N'essayez pas de seconde gestion de la mémoire. Il est généralement plus intelligent que vous Il n'y a aucune garantie que "FOO" sera inchangée. L'ensemble de votre 4k peut être libéré et realloc () peut déplacer votre mémoire ailleurs, invalidez donc tous les pointeurs que vous pouvez contenir.

Ceci est valable pour C & C ++ - Toutefois, l'utilisation de MALLOC ( ) En C ++, une mauvaise odeur de code et la plupart des gens s'attendaient à ce que vous utilisiez nouveau () pour allouer le stockage. Et la mémoire allouée avec NEW () ne peut pas être réaffectée () ED - ou du moins, pas de manière portable. Les vecteurs STL seraient une approche bien meilleure en C ++


0 commentaires

5
votes

Vous n'avez pas "un pointeur alloué pour contenir 4096 octets", vous avez un pointeur à un bloc attribué de 4096 octets.

Si votre bloc a été attribué avec MALLOC () , realloc () vous permettra de réduire ou d'augmenter la taille du bloc. L'adresse de départ du bloc ne restera pas nécessairement la même, cependant.

Vous ne pouvez pas modifier l'adresse de démarrage d'un bloc de mémoire MALLOC D, ce qui est vraiment ce que votre deuxième scénario demande. Il n'ya également aucun moyen de diviser un bloc Malloc D.

Ceci est une limitation du malloc / calloc / / / libre API - et implémentations peut S'appuyer sur ces limitations (par exemple, garder les informations de comptabilité sur l'allocation immédiatement avant l'adresse de départ, ce qui permettrait de déplacer l'adresse de départ difficile.)

maintenant, MALLOC n'est pas le seul allocator, votre plate-forme ou votre plate-forme ou vos bibliothèques peut en fournir les autres, ou vous pouvez écrire votre propre (qui obtient la mémoire du système via MALLOC , mmap , virtualalloc ou un autre mécanisme), puis la remet à votre programme de la mode que vous désirez.

pour C ++, si vous allouez la mémoire avec std :: masloc , les informations ci-dessus s'appliquent. Si vous utilisez Nouveau et Supprimer , vous allociez des stockages pour et construire des objets, ce qui modifie ainsi la taille d'un bloc attribué n'a pas de sens - objets en C ++ sont une taille fixe.


0 commentaires