calling malloc function does't always call sbrk function internally? - c

I'm new to C and heap memory, below is my understanding about dynamic memory allocation, please correct me if I'm wrong:
Fact 1-When the first time calling malloc, malloc will call sbrk internally to move/grow the brk pointer(program break).
Fact 2-after calling malloc and free a couple of times, there could be free blocks between two allocated blocks, so if we call malloc again with a required size less than the size of free blocks, then this time malloc will not call sbrk internally, instead, malloc just modify one existing free block's structure(setting allocated bit ...etc) and return the address of this block.

There is nothing in the standard that says malloc() must move/grow the brk pointer to allocate memory. In fact, nowadays malloc() will often use mmap(..., MAP_ANONYMOUS, ...) internally to obtain memory.
It is likely that if there is a gap after repeated malloc() and free() calls, that the next malloc() might be able to allocate memory in the gap, such that no calls to sbrk() or mmap() are necessary. But again, there is no guarantee that this will actually happen.

Related

Why use calloc to initialize the allocated memory to zero?

We know that the heap is an area of demand-zero memory that begins immediately after the uninitialized data area and grows upward (toward higher addresses). By demand-zero, it means the first time the CPU touches a virtual page in heap area, the corresponding physical page will be all zeros.
If that is the case, then why there is a function calloc used to initialize the allocated memory to zero? Why do demand-zero pages need to be initialized zero again if they will be zero already when accessed?
Because after you've used the space and released it with free(), it might be allocated again. If you don't use calloc(), there's no guarantee that the memory will be zeroed on the second time it is used. (Calling free() does not zero the space.)
calloc does not necessarily have to initialize the memory to zero by itself. The description of calloc says that:
The space is initialized to all bits zero.
but it does not say that it is calloc that does this, just that the memory is initialized to zero by some mechanism. This is unlike malloc:
The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate.
calloc guarantees that the memory is zeroed, and malloc does not. If the contents of the block are copy-on-write zero pages, then calloc may know not to zero it again and is faster than malloc + memset, as memset would not know that the memory was already zeroed (unless the compiler optimizes malloc + memset(..., 0, ...) to calloc); on the other hand if the block is reused, then calloc needs to zero it, even if the caller would not care about zeroing, therefore a malloc would be faster than calloc if no zeroing is needed, because then calloc would indeed do effectively malloc + memset
In short, it's more portable to set the memory to zero explicitly if that's what your application needs; and faster to leave it alone if it doesn't. You don't have to use calloc() to get zero'd memory -- you could just use malloc() and zero it yourself (e.g.,using memset). But calloc() will give you zero'd memory more quickly, if it can take advantage of a platform-specific feature to get it.
the 'heap' memory will contain what ever trash was in memory when your program was loaded, (just like the stack)
It is up to your application to zero memory. There are a few ways to do that.
calloc()
a loop in your code
memset()
This is in part historical, and in part as a useful feature
We had heap with uninitialised memory (which was not zero), so more quick to get memory. Then this was discovered that this is a security problem, so much later, you get memory cleared to zero (and never memory set by other processes). Do not assume all systems will do it (especially on small embedded CPU, where CPU and bus access are expensive (time and power).
calloc is very handy, when you allocate arrays (as you see, the signature is done for arrays). Often on arrays, you want to initialize values to zero. A loop is very slow, and static had already the initialization to zero. We have two possibilities: initialized memory with calloc or uninitialised memory with malloc.
Note: malloc doesn't guarantee to give you all zeros: it could give you already allocated (from your process) and freed memory. Just now new memory given by kernel is zeroed (e.g. with brk/sbrk, which is sometime called by malloc/calloc, in case of lack of free memory in existing heap memory). These are two different allocation of memory.

How does malloc obtain memory from the heap?

We know that malloc calls mmap internally. But mmap doesn't necessarily map to the heap as mmap can map objects to any area in virtual memory, then how does malloc do internally to make sure that the requested size of memory is from the heap?
When malloc uses mmap to allocate memory, it doesn‘t care where the memory comes from — it delegates the allocation to mmap, and relies on that to provide a usable block of memory.
In the GNU C library (and probably in other implementations too), such allocations are tracked separately from the allocations managed using sbrk. All operations involving mmaped allocations are also delegated (reallocation and freeing).
From the kernel’s perspective, such allocations are off-heap, i.e. after the program break. From the programmer’s perspective, they’re all the same; the main practical consequences compared to sbrk-only allocations is that you can’t assume that allocated blocks are within the program break, or that the address space between two allocated blocks is accessible, but you shouldn‘t do that anyway.
See also the POSIX specification for malloc — it doesn’t say anything about the heap.

What different attributes between malloc() and VirtualAlloc() to allocate a memory in windows?

The VirtualAlloc() will allocate a virtual memory page that have some attributes (by the parameter "fdwProtect").
What about the memory that allocated by malloc() ?Is that have same attributes?
Is the memory by malloc() have attributes that "commintting" or "reserving" ?
Further more, what about other C/C++ lib function?
VirtualAlloc
This function allows you to specify additional options for memory allocation. But it allocates memory in large page with a minimum indicated by GetLargePageMinimum, you can commit, reserve with it. It's not for general use. Memory allocated by this function is automatically initialized to zero.
malloc
The standard C version to allocate memory. Prefer it if you are writing in C rather than C++, and your code needs to work on on other platforms, or someone specifically says that you need to use it. It's quite possible that, on Windows, malloc would be implemented on top of HeapAlloc. malloc can allocate any chunk of memory, it doesn't have any concept to commit and reserve by current standard. Memory allocated by this function is not initialized.

alloc, malloc, and alloca — What's the difference?

I was under the impression that alloc in Objective-C (when we invoke [anyObject alloc] is actually implementing C function malloc and the memory getting allocated in heap, but could not find anywhere the answer for this.
Also, while searching for alloc, I found alloca which allocates memory in stack. If I am not wrong, alloc allocates memory in heap to create objects.
So, what is the difference between alloc and malloc (and alloca)? Can anyone please summarize?
alloc() is not a standard C library function. Some older compilers and libraries contain an <alloc.h> library which provides some memory allocation functions, but this is not standard. The Microsoft Visual C++ runtime includes an Alloc() function which is somewhat similar to malloc(), but this is also not part of the C standard.
malloc() allocates memory on the process heap. Memory allocated using malloc() will remain on the heap until it is freed using free().
alloca() allocates memory within the current function's stack frame. Memory allocated using alloca() will be removed from the stack when the current function returns. alloca() is limited to small allocations.
Situations where alloca() is appropriate are rare. In almost all situations, you should use malloc() to allocate memory.
The alloc function is used to allocate a region or block of size bytes in length of the heap.
The malloc function is used to allocate heap storage. Its name stands for memory allocation.
I don't remember the verbatim statement from the book C++ Primer, but there is a major difference between the functions. For example new in C++ allocates memory, but it also constructs the data into the memory. The std::allocator allocates memory, but doesn't call any constructor. The same is true for these C functions. One allocates but doesn't construct. One allocates and construct.

C - What does free() do to the memory?

I recoded malloc() free() and realloc().
I have a linked list with the pointers returned by malloc().
The question is : what does free() really do ?
Currently, I did a memset() to have the same behavior of free().
But was it better just to set a flag in my list as 'is free' rather than doing a memset() in order to make it faster ?
Free : Call will unlink / unallocate the memory pointed by pointer so that other process can use it.
Memset : Call will set a memory / fill a memory location. It won't unlink / unallocate a memory and memory remain allocated / occupied till the program exist. Which can cause memory leaks.
You can use valgrind tool to check memory leaks.
And it is a better practice to unlink / unallocate a memory if its not required.
Usually free(3) does not do anything to the memory itself. (If security or privacy is a concern, you should clear memory before freeing.)
If you want to implement malloc, you need to have some database of free memory blocks. When memory is freed you should join it with adjoint free memory, if there is any. If a complete page ends up unused, you should tell the kernel, that you don't need it anymore (depending on how you got that memory in the first place)
The C library function void free(void *ptr) deallocates the memory previously allocated by a call to calloc, malloc, or realloc.
You should use it to prevent memory leaks.

Resources