Simple implémentation C pour suivre la mémoire malloc / gratuit?
langage de programmation: C
plate-forme: BRAS
Compilateur: ANNONCES 1.2
J'ai besoin de garder une trace de simple melloc/free
appels dans mon projet. J'ai juste besoin d'obtenir une très idée de base de la façon dont beaucoup de segment de mémoire est requis lorsque le programme a attribué toutes ses ressources. Donc, j'ai fourni un wrapper pour la malloc/free
appels. Dans ces wrappers j'ai besoin d'incrémenter un mémoire en cours d'inventaire lors de l' malloc
est appelé et de décrémentation quand free
est appelé. Le malloc
cas est très simple car j'ai la taille à allouer de l'appelant. Je me demande comment traiter avec les free
cas que j'ai besoin de stocker le pointeur/taille de la cartographie quelque part. Ceci étant C, je n'ai pas de carte standard à mettre en œuvre facilement.
J'essaie d'éviter de liaison dans les bibliothèques afin préférerait *.c/h mise en œuvre.
Alors je me demande si il y a déjà une mise en œuvre simple un peut me conduire à. Si non, c'est la motivation pour aller de l'avant et de mettre en œuvre.
EDIT: Purement à des fins de débogage et ce code n'est pas fourni avec le produit.
EDIT: mise en œuvre Initiale basée sur la réponse de Makis. J'aimerais avoir des commentaires sur ce.
EDIT: Retravaillé la mise en œuvre
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <limits.h>
static size_t gnCurrentMemory = 0;
static size_t gnPeakMemory = 0;
void *MemAlloc (size_t nSize)
{
void *pMem = malloc(sizeof(size_t) + nSize);
if (pMem)
{
size_t *pSize = (size_t *)pMem;
memcpy(pSize, &nSize, sizeof(nSize));
gnCurrentMemory += nSize;
if (gnCurrentMemory > gnPeakMemory)
{
gnPeakMemory = gnCurrentMemory;
}
printf("PMemAlloc (%#X) - Size (%d), Current (%d), Peak (%d)\n",
pSize + 1, nSize, gnCurrentMemory, gnPeakMemory);
return(pSize + 1);
}
return NULL;
}
void MemFree (void *pMem)
{
if(pMem)
{
size_t *pSize = (size_t *)pMem;
//Get the size
--pSize;
assert(gnCurrentMemory >= *pSize);
printf("PMemFree (%#X) - Size (%d), Current (%d), Peak (%d)\n",
pMem, *pSize, gnCurrentMemory, gnPeakMemory);
gnCurrentMemory -= *pSize;
free(pSize);
}
}
#define BUFFERSIZE (1024*1024)
typedef struct
{
bool flag;
int buffer[BUFFERSIZE];
bool bools[BUFFERSIZE];
} sample_buffer;
typedef struct
{
unsigned int whichbuffer;
char ch;
} buffer_info;
int main(void)
{
unsigned int i;
buffer_info *bufferinfo;
sample_buffer *mybuffer;
char *pCh;
printf("Tesint MemAlloc - MemFree\n");
mybuffer = (sample_buffer *) MemAlloc(sizeof(sample_buffer));
if (mybuffer == NULL)
{
printf("ERROR ALLOCATING mybuffer\n");
return EXIT_FAILURE;
}
bufferinfo = (buffer_info *) MemAlloc(sizeof(buffer_info));
if (bufferinfo == NULL)
{
printf("ERROR ALLOCATING bufferinfo\n");
MemFree(mybuffer);
return EXIT_FAILURE;
}
pCh = (char *)MemAlloc(sizeof(char));
printf("finished malloc\n");
//fill allocated memory with integers and read back some values
for(i = 0; i < BUFFERSIZE; ++i)
{
mybuffer->buffer[i] = i;
mybuffer->bools[i] = true;
bufferinfo->whichbuffer = (unsigned int)(i/100);
}
MemFree(bufferinfo);
MemFree(mybuffer);
if(pCh)
{
MemFree(pCh);
}
return EXIT_SUCCESS;
}
source d'informationauteur dubnde | 2009-05-12
Vous devez vous connecter pour publier un commentaire.
Vous pourrait allouer quelques octets supplémentaires dans votre enveloppe et de mettre un id (si vous voulez être en mesure de couple malloc() et free()) ou tout simplement de la taille. Juste malloc() que beaucoup plus de mémoire, de stocker des informations au début de votre bloc de mémoire et déplacez le pointeur de vous renvoyer à ce nombre d'octets à transférer.
Cela peut, d'ailleurs, aussi être facilement utilisé pour la clôture des pointeurs/empreintes digitales, et un tel.
Soit, vous pouvez avoir accès à l'intérieur, les tables utilisées par
malloc
/free
(voir à cette question: Où puis-malloc() /free() Magasin Alloué Tailles et des Adresses? pour d'autres conseils), ou vous devez gérer vos propres tableaux dans vos papiers d'emballage.Vous pouvez toujours utiliser valgrind au lieu de rouler votre propre mise en œuvre. Si vous n'avez pas de soins sur la quantité de mémoire que vous allouez vous pouvez utiliser un moyen encore plus simple de mise en œuvre: (je l'ai fait très rapidement, il pourrait donc y avoir des erreurs et je me rends compte que c'est pas le plus efficace de mise en œuvre. Le pAllocedStorage devrait être donnée d'une taille initiale et d'augmenter par un facteur de redimensionnement etc. mais vous obtenez l'idée.)
EDIT: j'ai manqué que c'était pour les BRAS, à ma connaissance, valgrind est pas disponible sur le BRAS de façon à ce que pourrait ne pas être une option.
Je voudrais utiliser rmalloc. C'est une simple bibliothèque (en fait, il est à seulement deux fichiers) pour déboguer l'utilisation de la mémoire, mais il possède aussi un support pour les statistiques. Puisque vous avez déjà des fonctions wrapper, il devrait être très facile à utiliser rmalloc. Gardez à l'esprit que vous devez également remplacer strdup, etc.
Votre programme peut également besoin d'intercepter le realloc(), calloc(), getcwd() (comme il peut allouer de la mémoire lorsque la mémoire tampon est NUL dans certaines implémentations) et peut-être strdup() ou une fonction similaire, si elle est prise en charge par votre compilateur
Si vous êtes en cours d'exécution sur
x86
vous pouvez simplement exécuter le binaire sous valgrind et il permettra de réunir toutes ces informations pour vous, en utilisant le standard de mise en œuvre demalloc
etfree
. Simple.J'ai essayé quelques-uns des mêmes techniques mentionnées sur cette page et liquidation ici à partir d'une recherche sur google. Je sais que cette question est ancienne, mais je voulais ajouter pour l'enregistrement...
1) est-ce que votre système d'exploitation fournissent pas les outils pour voir combien de segment de mémoire est utilisée dans un processus en cours d'exécution? Je vois que vous parlez de BRAS, de sorte que ce pourrait bien être le cas. Dans la plus complète de Systèmes d'exploitation, c'est juste une question de l'utilisation d'un cmd-outil en ligne pour voir la taille du tas.
2) Si elle est disponible dans votre libc, sbrk(0) sur la plupart des plateformes de vous raconter la fin de l'adresse de votre segment de données. Si vous l'avez, tout ce que vous devez faire est de copier l'adresse au début de votre programme (par exemple, startBrk=sbrk(0)), alors, à tout moment, à votre taille allouée est sbrk(0) - startBrk.
3) Si elle est partagée, les objets peuvent être utilisés, vous êtes dynamiquement des liens vers votre libc, et vos OS runtime chargeur a quelque chose comme une variable d'environnement LD_PRELOAD, vous trouverez peut-être plus utile de construire votre propre objet partagé qui définit le réel de la libc fonctions avec les mêmes symboles (malloc(), pas MemAlloc()), alors le chargeur charge votre lib premier et "interposer" les fonctions de la libc. Vous pouvez en outre obtenir l'adresse de l'effectif des fonctions de la libc avec dlsym() et le RTLD_NEXT drapeau de sorte que vous pouvez faire ce que vous faites ci-dessus, sans avoir à recompiler tout votre code pour utiliser votre malloc/free wrappers. Il est alors tout à l'exécution de la décision lorsque vous démarrez votre programme (ou tout autre programme qui correspond à la description dans la première phrase) lorsque vous définissez une variable d'environnement comme LD_PRELOAD=mymemdebug.et puis l'exécuter. (google pour objet partagé interposition.. c'est une grande technique et utilisé par de nombreux débogueurs/profileurs)