home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / lang / c / 16947 < prev    next >
Encoding:
Internet Message Format  |  1992-11-21  |  3.0 KB

  1. Path: sparky!uunet!paladin.american.edu!news.univie.ac.at!hp4at!mcsun!sun4nl!and!jos
  2. From: jos@and.nl (Jos Horsmeier)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: Memory Info.
  5. Message-ID: <3900@dozo.and.nl>
  6. Date: 21 Nov 92 12:54:31 GMT
  7. References: <1992Nov20.130913.20148@sifon.cc.mcgill.ca>
  8. Organization: AND Software BV Rotterdam
  9. Lines: 92
  10.  
  11. In article <1992Nov20.130913.20148@sifon.cc.mcgill.ca> vugranam@pike.ee.mcgill.ca (Vugranam Chakravarthy Sreedhar) writes:
  12. |
  13. |Given a pointer to a object that has been previously allocated using
  14. |one of the allocation routine, how can I get the
  15. |size of the object.
  16.  
  17. If you want to do that in a portable way, I have to disappoint you: there's
  18. no way to determine the size of an allocated object. but read on ...
  19.  
  20. |char *c;
  21. |long  x ; 
  22. |
  23. |c = (char *) malloc (100) ;
  24. |x = mem_size(c) ;   /* x is block size of c, which in this case is 100 */
  25. |
  26. |I want to use this to keep track of memory statistics. Now what I do is
  27. |to pass the size to my memory routines. Like
  28. |
  29. |int *mymalloc(size) ;  /* this is easy */
  30. |int myfree(char *, long size)   /* I don't like this !!*/
  31.  
  32. Two solutions come to mind:
  33.  
  34. 1. Use an array of the followingt objects:
  35.  
  36. typedef struct {
  37.     void   *object;
  38.     size_t size;
  39. } object_t;
  40.  
  41. and write your own my_malloc and my_free routines. my_malloc has to
  42. find an empty slot in that array and store the pointer and the size
  43. of the allocated object into that slot. my_free has to find the 
  44. specified slot and mark it as free again. The bad thing about this
  45. solution is the fixed size array. You cannot allocated more objects
  46. than there are slots in the array, without freeing at least one of
  47. the other objects before. reallocating the array of slots seems a
  48. bit clumsy to me, but it can be done.
  49.  
  50. 2. Allocate a bit more memory than was requested and stick the size
  51. into the additionally allocated bytes. my_malloc and my_free would 
  52. look something like this:
  53.  
  54. void *my_malloc(size_t size) {
  55.  
  56.     size_t *object;
  57.  
  58.     size+= SLOTSIZE;            /* make room for size */
  59.  
  60.     if (object= malloc(size)) {
  61.         *object= size;            /* register the size */    
  62.         ((char*)object)+= SLOTSIZE;    /* step over size slot */
  63.     }
  64.     return (void*) object;
  65. }
  66.  
  67. void my_free(void *object) {
  68.  
  69.     if (object) {
  70.         ((char*)object)-= SLOTSIZE;    /* object points to size */
  71.         free(object);
  72.     }
  73. }
  74.  
  75. SLOTSIZE is a manifest constant that has to obey to the following rules:
  76.  
  77. - SLOTSIZE >= sizeof(size_t)
  78.  
  79. - SLOTSIZE is the smallest multiple of the most stringent alignment
  80.   size needed on your machine, e.g. on a SPARC the alignment of a double
  81.   is 8 bytes (the most stringent alignement), where the alignment of a
  82.   size_t is 4 bytes, so SLOTSIZE would be 8 in this situation. 
  83.  
  84. Your wanted function mem_size would look something like this:
  85.  
  86. size_t mem_size(void *object) {
  87.  
  88.     if (object) 
  89.         return *((size_t*)((char*)object)-SLOTSIZE);
  90.     else
  91.         return 0;        /* or whatever */
  92. }
  93.  
  94. All this casting and byte fiddling works just because malloc always
  95. returns a pointer to a chunk of memory that is always suitably aligned
  96. for all types of objects.
  97.  
  98. I hope this helps a bit.
  99.  
  100. kind regards,
  101.  
  102. Jos aka jos@and.nl
  103.