[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.