help-gplusplus
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Heap, Arrays and Structures


From: Paul Pluzhnikov
Subject: Re: Heap, Arrays and Structures
Date: Wed, 05 Dec 2007 21:29:14 -0800
User-agent: Gnus/5.1006 (Gnus v5.10.6) XEmacs/21.4 (Jumbo Shrimp, linux)

R Karthick <karthick.ramachandran@gmail.com> writes:

> This might be a very primitive question. But I want to be clear about
> the allocation mechanism adopted by C++.

You are not investigating "allocation mechanism adopted by C++"
(whatever that means). You are investigating a particular malloc
implementation on your system.

> This program uses a dynamically allocated structure and array.

> extern "C"  void* sbrk( ssize_t incr );
> struct foo_structure
> {
>       char foo_char[50000];
> };

Note that the size of foo_struct is 50000 bytes.

>       int *foo_int;
>       foo_int = new int[50000];

Don't do that. Do this instead (and look up RAII):

        int *foo_int = new int[50000];

Also note, that the size of dynamically-allocated array is (on
32-bit system) is 200000 bytes. You would have gotten a different
(and probably less confusing) result if you had used 'new int[12500]'
instead.

...
> LOCAL VARIABLES
> Address of &d1: 0xbf9d30f8
...
> HeapEnd: 0x8077000
>
> ARRAY
> Address of &foo_int: 0xb7c70008

That is incorrect: you are *not* printing &foo_int, you are printing
the *value* of foo_int. There is a big difference.

> Address of &foo_int[0]: 0xb7c70008
...
> STRUCTURE
> Address of foo_struct: 0x804a008
> Address of &foo: 0xbf9d30fc
> Address of &foo->foo_char[0]: 0x804a008
...
> I understand that local variables go into the stack in the 0xb9
> address range.

There isn't a single '0xb9...' anywhere in your output. Did you
mean 0xbf9..., or something else?

> I can see that "STRUCTURE", foo_struct is getting
> allocated in the heap. (Note: heap end is, 0x8077000). I  am confused
> about the allocation of the "ARRAY", foo_int.  I was hoping as the
> array is also initialized using "new"

It is.

> it will take some memory from the heap address range.

It does.

> I would like to know where exactly the array
> is allocated. (0xb7c70008 ... ).

On the heap. But it just so happens, that glibc does *not* use sbrk()
to obtain memory for large heap allocations, and uses mmap() instead.

The threshold can be found by looking in e.g.
glibc-2.3.3-200405070341/malloc/malloc.c, which has:

/*
  M_MMAP_THRESHOLD is the request size threshold for using mmap()
  to service a request. Requests of at least this size that cannot
  be allocated using already-existing space will be serviced via mmap.
  (If enough normal freed space already exists it is used instead.)

  Using mmap segregates relatively large chunks of memory so that
  they can be individually obtained and released from the host
  system. A request serviced through mmap is never reused by any
  other request (at least not directly; the system may just so
  happen to remap successive requests to the same locations).

  Segregating space in this way has the benefits that:

   1. Mmapped space can ALWAYS be individually released back
      to the system, which helps keep the system level memory
      demands of a long-lived program low.
   2. Mapped memory can never become `locked' between
      other chunks, as can happen with normally allocated chunks, which
      means that even trimming via malloc_trim would not release them.
   3. On some systems with "holes" in address spaces, mmap can obtain
      memory that sbrk cannot.

  However, it has the disadvantages that:

   1. The space cannot be reclaimed, consolidated, and then
      used to service later requests, as happens with normal chunks.
   2. It can lead to more wastage because of mmap page alignment
      requirements
   3. It causes malloc performance to be more dependent on host
      system memory management support routines which may vary in
      implementation quality and may impose arbitrary
      limitations. Generally, servicing a request via normal
      malloc steps is faster than going through a system's mmap.

  The advantages of mmap nearly always outweigh disadvantages for
  "large" chunks, but the value of "large" varies across systems.  The
  default is an empirically derived value that works well in most
  systems.
*/
...
#ifndef DEFAULT_MMAP_THRESHOLD
#define DEFAULT_MMAP_THRESHOLD (128 * 1024)
#endif


Note that sizeof(foo_structure) < DEFAULT_MMAP_THRESHOLD < size of foo_int 
allocation

Cheers,

P.S. Your question has absolutely nothing to do with gcc and g++,
and you may have better luck in Linux-specific newsgroups.

P.P.S. Wait at least a couple of days before deciding that nobody
is going to respond to you and re-posting the same message to
other groups. Better yet, think ahead and cross-post a *single*
message to all groups you think might be relevant.

-- 
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]