·¢²©ÎÄ
LinuxÄÚºËѧϰ

ericxiao.blog.chinaunix.net

½ä½¾,½äÔê,¾²ÐÄ,¾²Æø......   
¸öÈË×ÊÁÏ
  • ²©¿Í·ÃÎÊ£º1490179
  • ²©ÎÄÊýÁ¿£º109
  • ²©¿Í»ý·Ö£º30119
  • ²©¿ÍµÈ¼¶£º´ó½«
  • ¹Ø×¢ÈËÆø£º 19
  • ×¢²áʱ¼ä£º2007-10-22 14:58:36
¶©ÔÄÎҵIJ©¿Í
  • ¶©ÔÄ
  • ¶©Ôĵ½Ïʹû
  • ¶©Ôĵ½×¥Ïº
  • ¶©Ôĵ½Google
×ÖÌå´óС£º´ó ÖРС²©ÎÄ
·ÖÀࣺ linuxÄÚ´æ¹ÜÀí

Î壺mallocµÄʵÏÖ£º

·ÖÎöÍêFAµÄ²Ù×÷Ö®ºó£¬¾Í¿ÉÒÔÀ´·ÖÎömallocÓëfreeµÄ¾ßÌåʵÏÖÁË¡£ÏÈ·ÖÎömalloc

ÔÚ·ÖÎömalloc֮ǰ£¬ÓбØÒª·ÖÎöһϼ¸¸öÎÊÌ⣺

1£º´ÓÉÏÃæ__heap_free_area_allocº¯ÊýµÄ·ÖÎö¿ÉÒÔ¿´µ½¡£·ÖÅäÄÚ´æÊ±£¬Ö»Êǵ÷ÕûÁË¿ÕÏÐÇøµÄ´óС»òÕßÊÇ·ÖÅäÁËÕû¸ö¿ÕÏÐÇø¡£ÄÇÊÍ·ÅÄÚ´æµÄʱºò£¬Ôõô²ÅÄÜÖªµÀÒªÊͷŶàÉÙÄØ¡££¨free()Öв¢Ã»ÓÐÖ¸´óС²ÎÊý£©?

2:Èç¹û¶ÑµÄ¿Õ¼ä²»¹»ÁË£¬¸ÃÔõô°ì£¿ÈçºÎÍ¢É죿

¹ØÓÚ1£ºÓÃmalloc·ÖÅäÄÚ´æµÄʱºò£¬Ëü¾­³£Òª¶à·ÖÅäÒ»µã£¬ÒòΪÔÚËù·ÖµÃÄÚ´æÇ°ÃæÒª±£ÁôһС¶ÎÀ´´æ´¢Ëù·ÖÅäµÄ´óС¡£ÕâÑùÔÚÊÍ·ÅÄÚ´æµÄʱºò£¬¾ÍÄÜÕÒµ½ÒªÊͷŵĴóСÁË¡£ÈçͼËùʾ£º

 

MALLOC_SIZE (mem)£ºÓÃÀ´·µ»ØËù·ÖµÃµÄÆðʼµØÖ·ÎªmemµÄÄÚ´æ¿é´óС

MALLOC_BASE (mem)£ºÓÃÀ´¼ÆËãËù·ÖÅäµÄÆðʼµØÖ·ÎªmemµÄÄÚ´æ¿éËù¶ÔÓ¦µÄʵ¼ÊµØÖ·

ÆäʵMALLOC_SIZE (mem)Êǽ«µØÖ·memÍ˺óMALLOC_HEADER_SIZE¸öµ¥Î»£¬È»ºóÔÙȡֵ£¬¾ÍÄܵõ½´óСÁË¡£

¶ÔÓÚ¶þ£º¿ÉÒÔµ÷ÓÃbrk()»òÕßmmapÀ´À©Õ¹Êý¾Ý¶Î¡£¹ØÓÚÕⲿ·Ý£¬ÒÔºóÎÒÔÙ¸ø³öרÌâ·ÖÎö¡£

ÖÕÓÚ¿ÉÒÔµ½¾ßÌåµÄ´úÂëʵÏÖÁË£º

 

malloc (size_t size)

{

     //ÂÔ¹ýµ÷ÊÔ´úÂë

#ifdef MALLOC_DEBUGGING

  static int debugging_initialized = 0;

  if (! debugging_initialized)

    {

      debugging_initialized = 1;

      __malloc_debug_init ();

    }

  if (__malloc_check)

    __heap_check (&__malloc_heap, "malloc");

#endif

 

     //²ÎÊýÓÐЧÐÔ¼ì²â¡£ÕâÀïûÓмì²â²ÎÊýΪ¸ºµÄÇé¿ö

  if (size == 0)

    return 0;

 

  return malloc_from_heap (size, &__malloc_heap);

}

º¯ÊýתÈëmalloc_from_heap (size, &__malloc_heap)

ËüµÄʵÏÖÈçÏ£º

//´«Èë²ÎÊý£º

//size:ÏëÒª·ÖÅäµÄÄÚ´æ´óС¡£heap£º¼´Îª__malloc_heap

static void *

malloc_from_heap (size_t size, struct heap *heap)

{

  void *mem;

  MALLOC_DEBUG (1, "malloc: %d bytes", size);

  /* Include extra space to record the size of the allocated block.  */

//ʵ¼ÊÒª·ÖÅäµÄ´óС£¬¼ûÇ°ÃæµÄ·ÖÎö

  size += MALLOC_HEADER_SIZE;

//Ϊ·ÀÖ¹¾ºÌ¬£¬¼ÓËø

  __heap_lock (heap);

 

  /* First try to get memory that's already in our heap.  */

//Ê×Ïȳ¢ÊÔ´Óheap·ÖÅäÄÚ´æ.Õ⺯Êý¼ûÇ°ÃæµÄ·ÖÎö

  mem = __heap_alloc (heap, &size);

     //½âËø

  __heap_unlock (heap);

 

  if (unlikely (! mem))

     {

     //Èç¹û·ÖÅäʧ°Ü£¬ÄǾÍ˵Ã÷¿ÕÏÐÇø²»×㣬ÏòÄÚºËÉêÇë

      void *block;

     //¼ÆËãÒªÏòÄÚºËÉêÇëµÄ´óС£¬ÖÁÉÙҪΪһ¸öpage£¬¼´4096

      size_t block_size

     = (size < MALLOC_HEAP_EXTEND_SIZE

        ? MALLOC_HEAP_EXTEND_SIZE

        : MALLOC_ROUND_UP_TO_PAGE_SIZE (size));

 

      /* Allocate the new heap block.  */

//Á½ÖÖ·½Ê½£¬Ò»ÖÖÊÇsbrk() ÁíÒ»ÖÖÊÇmmap£¨£©¡£ºóÃæ×öΪһ¸öרÌâ½éÉÜ

#ifdef MALLOC_USE_SBRK

 

      __malloc_lock_sbrk ();

 

      /* Use sbrk we can, as it's faster than mmap, and guarantees

      contiguous allocation.  */

      block = sbrk (block_size);

      if (likely (block != (void *)-1))

     {

       /* Because sbrk can return results of arbitrary

          alignment, align the result to a MALLOC_ALIGNMENT boundary.  */

       long aligned_block = MALLOC_ROUND_UP ((long)block, MALLOC_ALIGNMENT);

       if (block != (void *)aligned_block)

         /* Have to adjust.  We should only have to actually do this

            the first time (after which we will have aligned the brk

            correctly).  */

         {

           /* Move the brk to reflect the alignment; our next allocation

          should start on exactly the right alignment.  */

           sbrk (aligned_block - (long)block);

           block = (void *)aligned_block;

         }

     }

 

      __malloc_unlock_sbrk ();

 

#else /* !MALLOC_USE_SBRK */

 

      /* Otherwise, use mmap.  */

      block = mmap (0, block_size, PROT_READ | PROT_WRITE,

              MAP_SHARED | MAP_ANONYMOUS, 0, 0);

 

#endif /* MALLOC_USE_SBRK */

 

      if (likely (block != (void *)-1))

     {

#if !defined(MALLOC_USE_SBRK) && defined(__UCLIBC_UCLINUX_BROKEN_MUNMAP__)

       struct malloc_mmb *mmb, *prev_mmb, *new_mmb;

#endif

 

       MALLOC_DEBUG (1, "adding system memroy to heap: 0x%lx - 0x%lx (%d bytes)",

              (long)block, (long)block + block_size, block_size);

 

       /* Get back the heap lock.  */

       __heap_lock (heap);

 

       /* Put BLOCK into the heap.  */

         //½«ÉêÇëµÄÄÚ´æ¼ÓÈëheap

       __heap_free (heap, block, block_size);

 

       MALLOC_DEBUG_INDENT (-1);

 

       /* Try again to allocate.  */

     //ÖØÐÂÏòheapÉêÇëÄںˣ¬ÒòΪ´ËʱÒѾ­ÓÐ×ã¹»µÄ¿ÕÏÐÄÚ´æÁË

       mem = __heap_alloc (heap, &size);

 

       __heap_unlock (heap);

 

#if !defined(MALLOC_USE_SBRK) && defined(__UCLIBC_UCLINUX_BROKEN_MUNMAP__)

       /* Insert a record of BLOCK in sorted order into the

          __malloc_mmapped_blocks list.  */

 

       for (prev_mmb = 0, mmb = __malloc_mmapped_blocks;

            mmb;

            prev_mmb = mmb, mmb = mmb->next)

         if (block < mmb->mem)

           break;

 

       new_mmb = malloc_from_heap (sizeof *new_mmb, &__malloc_mmb_heap);

       new_mmb->next = mmb;

       new_mmb->mem = block;

       new_mmb->size = block_size;

 

       if (prev_mmb)

         prev_mmb->next = new_mmb;

       else

         __malloc_mmapped_blocks = new_mmb;

 

       MALLOC_MMB_DEBUG (0, "new mmb at 0x%x: 0x%x[%d]",

                  (unsigned)new_mmb,

                  (unsigned)new_mmb->mem, block_size);

#endif /* !MALLOC_USE_SBRK && __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */

     }

    }

 

  if (likely (mem))

    /* Record the size of the block and get the user address.  */

    {

         //ÒѾ­·ÖµÃÁËÄڴ棬µ÷Õû·ÖµÃµÄÄڴ棬Áô³öд´óСµÄ¿Õ¼ä£¬µ÷ÕûÒª·µ»Ø¸ø³ÌÐòµÄµØÖ·

      mem = MALLOC_SETUP (mem, size);

 

      MALLOC_DEBUG (-1, "malloc: returning 0x%lx (base:0x%lx, total_size:%ld)",

             (long)mem, (long)MALLOC_BASE(mem), (long)MALLOC_SIZE(mem));

    }

  else

    MALLOC_DEBUG (-1, "malloc: returning 0");

 

  return mem;

}

¸ú×ÙÒ»ÏÂMALLOC_SETUP (mem, size):

#define MALLOC_SETUP(base, size)  \

  (MALLOC_SET_SIZE (base, size), (void *)((char *)base + MALLOC_HEADER_SIZE))

#define MALLOC_SET_SIZE(base, size)  (*(size_t *)(base) = (size))

MALLOC_SET_SIZE,½«´óСдÈëÄڴ濪ʼµÄǰһ²¿·Ý¡£

Base+ MALLOC_HEADER_SIZE:µØÖ·ÉÏÒÆMALLOC_HEADER_SIZE¸öµ¥Î»

²©¿ÍÍÆ¼öÎÄÕÂ
Ç×£¬Äú»¹Ã»ÓеǼ,Çë[µÇ¼]»ò[×¢²á]ºóÔÙ½øÐÐÆÀÂÛ