Nehil said:
well, i agree that sbrk(int) is implementation defined, but don't u
think malloc must be using *something* like sbrk or brk to request the
memory chunk from OS.
Only for very loose definitions of "something like": in particular,
if you *define* _really_deep_malloc_magic() as being "something like
sbrk() or brk()" just on the basis that memory gets allocated
*somehow*, then yeah, of course. But the internals of malloc() differ
quite a bit between operating systems. The sbrk() semantics imply
that there is a linear "data space" that the operating system
appends onto the end of in order to satisfy allocation requests.
The reality might be very different for systems operating in
real memory mode, or for systems that use memory pools (different
allocation areas for different memory size requests).
One of the better known high performance malloc libraries for some
Unices uses mmap() requests against a base file descriptor open on
/dev/zero with copy-on-write semantics set; the mmap() requests get
mapped into some convenient place in the virtual memory space of the
process, potentially no-where near (in virtual space) anything else,
and potentially with "guard pages" to reduce the effect of overrunning
the allocated memory -- the important semantic detail of which
is that adjacent malloc() requests requiring new memory might
well not be virtually adjacent as implied by sbrk() semantics.
do u know some poratble way of taking memory from OS? please tell me.
malloc() and calloc(). Anything lower level is OS specific.
Now, let say i have a link list as follows :
header-->NODE1 => NODE2 => NODE3 => NODE4 => NULL
is there any way to merge the two nodes or to break a node in two
parts?
*If* you know that there was one big object which has been
sub-divided, then of course you can merge adjacent subdivisions
of it, or subdivide parts yourself. That's just standard linked
list manipulation, and the convenience of it depends upon
the representation and structures you used. The problems arise
if the objects you want to merge might not originally be part
of one original big object.
Are you trying to write your own memory allocator? If so, then
it would likely be a lot easier for you to find an allocator
that is already written. If you don't want to do that, then the
first thing you have to do, before you start worrying about linked
list manipulation, is to write up a list of the properties you
want the allocator to have. Is allocation speed the most important? Is
reducing memory fragmentation important? If allocation speed
is the most important, then is it permissible if the average case is
very fast, but the worst case is noticably slow? Does the user
of the allocator need to be able to use standard C pointers to point
into the allocated area, or are "array semantics" sufficient,
in which the use provides a base address and an offset and a routine
you provided gets or sets a value there? Because if you can get
away with "array semantics", then you can pause internally and
move memory around (e.g., pack fragments together to leave a bigger
free space) without worrying that something had a pointer to
memory and the next time they go to use the pointer, the underlying
value has moved. Etc., etc.. You have to decide on the crucial
design goals before you work on the internal representation.