Ainsi, dans la plupart des implémentations, Malloc stocke une en-tête avant la mémoire allouée pour garder une trace de la taille de la mémoire allouée (afin qu'elle puisse faire librement et recalculococ). Quel est le contenu de l'en-tête?
J'ai écrit un code naïf pour le trouver, mais cela n'a aucun sens p> il renvoie p> Qu'est-ce qui se passe ici? P> P>
5 Réponses :
Vous causez comportement non défini fort>. Je crois ce que vous essayez de savoir est un détail de mise en œuvre pour les compilateurs et variera d'un compilateur au compilateur. P>
Essayer de lire au-delà des limites de la mémoire allouée est une UB. p>
Rien de tout cela n'est une de vos affaires (c'est un détail de mise en œuvre em>, opaque à l'utilisateur) et ce que vous faites est un comportement indéfini. C'est aussi loin que la norme va. < / P> Maintenant, si vous voulez être méchant et fouetter la mémoire, méfiez-vous que l'arithmétique du pointeur fonctionne dans des unités de taille de type (par exemple 4 pour int code>). Donc, vous devriez toujours jeter vos indications sur char * code> (ou une version non signée) pour ces shenanigans: p>
+1 Parce que "Shenanigans" est le seul moyen de décrire ce que l'OP essaie de faire. Je serais à accepter avec Ccikuttar et à dire que cela fait depuis que cette information serait stockée ailleurs dans une table.
Joe: Le plus facile à découvrir est de rechercher la mise en œuvre de MALLOC code>. Si c'est dlmalloc code> ou pt2malloc code> Vous pouvez probablement trouver le papier quelque part qui le décrit, car ceux-ci sont assez célèbres.
@Kerrek: Donc, je * (i__now_what_im_doing - 4) me donne la taille du tas alloué. Mais la taille Malloc_header augmente alors que j'alloque plus de mémoire. Est-ce normal?
@Brice: Je n'ai aucune idée, car tout cela est totalement plate-forme et la mise en œuvre dépendante. Votre meilleur pari est de regarder la mise en œuvre de votre propre MALLOC () code> et découvrez-vous ce qui est "normal". Vous pouvez également imprimer quelques octets supplémentaires à l'envers si vous aimez et voyez ce qui est là.
Je ne comprends pas pourquoi les gens critiquent la curiosité ......... Ces questions sont ce qui crée un programmeur de systèmes ....
@Hassansyed: Le programmeur curieux creusera quand même leur code de mise en œuvre. Le danger est l'apprenant Casual C qui trébuche sur une page comme celle-ci et commence à penser qu'ils peuvent faire des hypothèses. Je préférerais protéger le monde d'un cent hypothèses sans fondement que de fournir une utilité marginale à la véritablement curieuse.
Ceci est un comportement indéfini. Mais pour être parfaitement honnête, si vous êtes prêt à gratter dans les internes de MALLOC, la première chose à faire est de déterminer ce que votre malloc fait. P>
Une fois que vous avez déterminé cela, vous pouvez faire quelque chose de plus intelligent que d'accéder au hasard en dehors des limites de ce que vous avez attribué (qui est le problème ici). P>
Je suppose que vous voulez apprendre et voir comment la mémoire est allouée. J'ignorerais les réponses du comportement non définies. Ils ont raison (bien sûr) lorsque vous parlez de portabilité et de tels, mais ce n'est pas votre question. Je pense que c'est une très bonne idée d'essayer de déterminer comment l'allocation est faite. P>
D'abord, je vous encourageons à commencer à consulter la mise en œuvre MALLOC pour votre plate-forme. Si ce code n'est pas disponible, vous n'avez pas de chance et le seul pense que vous pouvez faire est Google pour indiquer comment l'attribution est effectuée. p>
Si vous exécutez Linux, vous pouvez regarder l'implémentation MALLOC de GLIBC ou UCLIBC. Voici un lien vers la mise en œuvre UCLIBC: http://git.uclibc.org/uclibc/tree/libc/stdlib/malloc/ malloc.c Le code a beaucoup de commentaires, mais peut être accablant. P>
Pour votre question, regardez http://git.uclibc.org/uclibc /tree/libc/stdlib/malloc/malloc.h à la ligne 104. quelle est la partie dont vous parlez. Vous voyez que la mise en page dépend de Malloc_header_size, qui peut être différente pour différents systèmes. En lisant le code, vous pouvez apprendre quels types à utiliser et sur lesquels le décalage de la taille de la mémoire est stocké (dans cette implémentation spécifique) p>
Bien sûr, ci-dessus est juste un exemple de mise en œuvre de UCLIBC pour vous aider à démarrer ... p>
Personne n'a vraiment répondu à l'endroit où le nombre "57" est venu de, alors voici ma compréhension de cela. p>
L'en-tête défini lors de l'utilisation de MALLOC ou de CALOC, au moins sur les architectures que j'ai utilisées, est la taille totale du morceau de mémoire sur le tas d'exécution, ainsi que de quelques "drapeaux booléens". P>
Vous avez demandé 12 INTS, avec chaque INT (probablement) 4 octets. 12x4 = 48. Un autre 4 octet, pour le bloc d'en-tête lui-même (le nombre 57), est ajouté à ce nombre, nous laissant à 52 ans.
Alors, pourquoi obtenez-vous 57? P>
Eh bien, MALLOC et CALOC ne demandent que la mémoire dans des morceaux de 8 bits, pour éviter les erreurs de bus. Le multiple supérieur supérieur de 8 est 56. P>
Maintenant, rappelez-vous que tout nombre divisible par 8 a une représentation binaire qui se terminera toujours par trois 0. Être le langage de conservation de la mémoire que c est, les compilateurs tirent parti de ce fait et utilisent les trois derniers 0 comme drapeaux booléens. P>
Dans ce cas particulier, le dernier drapeau booléen est défini, ajoutant 1 à 56, ce qui entraîne le numéro 57 lorsqu'il est lu comme INT. p>
Peut-être que dans votre mise en œuvre, il ne ...
Pourquoi cela n'a-t-il aucun sens? C'est peut-être le 57ème élément du petit tas de bloc. Ou quelque chose. Si vous voulez savoir, lisez la source.
Je m'attendais à
42 code> :-)(En réponse à votre commentaire supprimé :) My GCC MALLOC a des fonctions d'information. Découvrez
malloc.h code>; Je pense qu'ils s'appellentmalloc_info () code> etmalloc_stats () code>. Des liens vers une documentation appropriée seraient appréciés.