What is the difference between doing:
ptr = malloc(MAXELEMS * sizeof(char *));
And:
ptr = calloc(MAXELEMS, sizeof(char*));
When is it a good idea to use calloc over malloc or vice versa?
calloc() gives you a zero-initialized buffer, while malloc() leaves the memory uninitialized.
For large allocations, most calloc implementations under mainstream OSes will get known-zeroed pages from the OS (e.g. via POSIX mmap(MAP_ANONYMOUS) or Windows VirtualAlloc) so it doesn't need to write them in user-space. This is how normal malloc gets more pages from the OS as well; calloc just takes advantage of the OS's guarantee.
This means calloc memory can still be "clean" and lazily-allocated, and copy-on-write mapped to a system-wide shared physical page of zeros. (Assuming a system with virtual memory.) The effects are visible with performance experiments on Linux, for example.
Some compilers even can optimize malloc + memset(0) into calloc for you, but it's best to just use calloc in the source if you want zeroed memory. (Or if you were trying to pre-fault it to avoid page faults later, that optimization will defeat your attempt.)
If you aren't going to ever read memory before writing it, use malloc so it can (potentially) give you dirty memory from its internal free list instead of getting new pages from the OS. (Or instead of zeroing a block of memory on the free list for a small allocation).
Embedded implementations of calloc may leave it up to calloc itself to zero memory if there's no OS, or it's not a fancy multi-user OS that zeros pages to stop information leaks between processes.
On embedded Linux, malloc could mmap(MAP_UNINITIALIZED|MAP_ANONYMOUS), which is only enabled for some embedded kernels because it's insecure on a multi-user system.
A less known difference is that in operating systems with optimistic memory allocation, like Linux, the pointer returned by malloc isn't backed by real memory until the program actually touches it.
calloc does indeed touch the memory (it writes zeroes on it) and thus you'll be sure the OS is backing the allocation with actual RAM (or swap). This is also why it is slower than malloc (not only does it have to zero it, the OS must also find a suitable memory area by possibly swapping out other processes)
See for instance this SO question for further discussion about the behavior of malloc
One often-overlooked advantage of calloc is that (conformant implementations of) it will help protect you against integer overflow vulnerabilities. Compare:
size_t count = get_int32(file);
struct foo *bar = malloc(count * sizeof *bar);
vs.
size_t count = get_int32(file);
struct foo *bar = calloc(count, sizeof *bar);
The former could result in a tiny allocation and subsequent buffer overflows, if count is greater than SIZE_MAX/sizeof *bar. The latter will automatically fail in this case since an object that large cannot be created.
Of course you may have to be on the lookout for non-conformant implementations which simply ignore the possibility of overflow... If this is a concern on platforms you target, you'll have to do a manual test for overflow anyway.
The documentation makes the calloc look like malloc, which just does zero-initialize the memory; this is not the primary difference! The idea of calloc is to abstract copy-on-write semantics for memory allocation. When you allocate memory with calloc it all maps to same physical page which is initialized to zero. When any of the pages of the allocated memory is written into a physical page is allocated. This is often used to make HUGE hash tables, for example since the parts of hash which are empty aren't backed by any extra memory (pages); they happily point to the single zero-initialized page, which can be even shared between processes.
Any write to virtual address is mapped to a page, if that page is the zero-page, another physical page is allocated, the zero page is copied there and the control flow is returned to the client process. This works same way memory mapped files, virtual memory, etc. work.. it uses paging.
Here is one optimization story about the topic:
http://blogs.fau.de/hager/2007/05/08/benchmarking-fun-with-calloc-and-zero-pages/
There's no difference in the size of the memory block allocated. calloc just fills the memory block with physical all-zero-bits pattern. In practice it is often assumed that the objects located in the memory block allocated with calloc have initilial value as if they were initialized with literal 0, i.e. integers should have value of 0, floating-point variables - value of 0.0, pointers - the appropriate null-pointer value, and so on.
From the pedantic point of view though, calloc (as well as memset(..., 0, ...)) is only guaranteed to properly initialize (with zeroes) objects of type unsigned char. Everything else is not guaranteed to be properly initialized and may contain so called trap representation, which causes undefined behavior. In other words, for any type other than unsigned char the aforementioned all-zero-bits patterm might represent an illegal value, trap representation.
Later, in one of the Technical Corrigenda to C99 standard, the behavior was defined for all integer types (which makes sense). I.e. formally, in the current C language you can initialize only integer types with calloc (and memset(..., 0, ...)). Using it to initialize anything else in general case leads to undefined behavior, from the point of view of C language.
In practice, calloc works, as we all know :), but whether you'd want to use it (considering the above) is up to you. I personally prefer to avoid it completely, use malloc instead and perform my own initialization.
Finally, another important detail is that calloc is required to calculate the final block size internally, by multiplying element size by number of elements. While doing that, calloc must watch for possible arithmetic overflow. It will result in unsuccessful allocation (null pointer) if the requested block size cannot be correctly calculated. Meanwhile, your malloc version makes no attempt to watch for overflow. It will allocate some "unpredictable" amount of memory in case overflow happens.
from an article Benchmarking fun with calloc() and zero pages on Georg Hager's Blog
When allocating memory using calloc(), the amount of memory requested is not allocated right away. Instead, all pages that belong to the memory block are connected to a single page containing all zeroes by some MMU magic (links below). If such pages are only read (which was true for arrays b, c and d in the original version of the benchmark), the data is provided from the single zero page, which – of course – fits into cache. So much for memory-bound loop kernels. If a page gets written to (no matter how), a fault occurs, the “real” page is mapped and the zero page is copied to memory. This is called copy-on-write, a well-known optimization approach (that I even have taught multiple times in my C++ lectures). After that, the zero-read trick does not work any more for that page and this is why performance was so much lower after inserting the – supposedly redundant – init loop.
Number of blocks:
malloc() assigns single block of requested memory,
calloc() assigns multiple blocks of the requested memory
Initialization:
malloc() - doesn't clear and initialize the allocated memory.
calloc() - initializes the allocated memory by zero.
Speed:
malloc() is fast.
calloc() is slower than malloc().
Arguments & Syntax:
malloc() takes 1 argument:
bytes
The number of bytes to be allocated
calloc() takes 2 arguments:
length
the number of blocks of memory to be allocated
bytes
the number of bytes to be allocated at each block of memory
void *malloc(size_t bytes);
void *calloc(size_t length, size_t bytes);
Manner of memory Allocation:
The malloc function assigns memory of the desired 'size' from the available heap.
The calloc function assigns memory that is the size of what’s equal to ‘num *size’.
Meaning on name:
The name malloc means "memory allocation".
The name calloc means "contiguous allocation".
calloc is generally malloc+memset to 0
It is generally slightly better to use malloc+memset explicitly, especially when you are doing something like:
ptr=malloc(sizeof(Item));
memset(ptr, 0, sizeof(Item));
That is better because sizeof(Item) is know to the compiler at compile time and the compiler will in most cases replace it with the best possible instructions to zero memory. On the other hand if memset is happening in calloc, the parameter size of the allocation is not compiled in in the calloc code and real memset is often called, which would typically contain code to do byte-by-byte fill up until long boundary, than cycle to fill up memory in sizeof(long) chunks and finally byte-by-byte fill up of the remaining space. Even if the allocator is smart enough to call some aligned_memset it will still be a generic loop.
One notable exception would be when you are doing malloc/calloc of a very large chunk of memory (some power_of_two kilobytes) in which case allocation may be done directly from kernel. As OS kernels will typically zero out all memory they give away for security reasons, smart enough calloc might just return it withoud additional zeroing. Again - if you are just allocating something you know is small, you may be better off with malloc+memset performance-wise.
There are two differences.
First, is in the number of arguments. malloc() takes a single argument (memory required in bytes), while calloc() needs two arguments.
Secondly, malloc() does not initialize the memory allocated, while calloc() initializes the allocated memory to ZERO.
calloc() allocates a memory area, the length will be the product of its parameters. calloc fills the memory with ZERO's and returns a pointer to first byte. If it fails to locate enough space it returns a NULL pointer.
Syntax: ptr_var = calloc(no_of_blocks, size_of_each_block);
i.e. ptr_var = calloc(n, s);
malloc() allocates a single block of memory of REQUSTED SIZE and returns a pointer to first byte. If it fails to locate requsted amount of memory it returns a null pointer.
Syntax: ptr_var = malloc(Size_in_bytes);
The malloc() function take one argument, which is the number of bytes to allocate, while the calloc() function takes two arguments, one being the number of elements, and the other being the number of bytes to allocate for each of those elements. Also, calloc() initializes the allocated space to zeroes, while malloc() does not.
Difference 1:
malloc() usually allocates the memory block and it is initialized memory segment.
calloc() allocates the memory block and initialize all the memory block to 0.
Difference 2:
If you consider malloc() syntax, it will take only 1 argument. Consider the following example below:
data_type ptr = (cast_type *)malloc( sizeof(data_type)*no_of_blocks );
Ex: If you want to allocate 10 block of memory for int type,
int *ptr = (int *) malloc(sizeof(int) * 10 );
If you consider calloc() syntax, it will take 2 arguments. Consider the following example below:
data_type ptr = (cast_type *)calloc(no_of_blocks, (sizeof(data_type)));
Ex: if you want to allocate 10 blocks of memory for int type and Initialize all that to ZERO,
int *ptr = (int *) calloc(10, (sizeof(int)));
Similarity:
Both malloc() and calloc() will return void* by default if they are not type casted .!
The calloc() function that is declared in the <stdlib.h> header offers a couple of advantages over the malloc() function.
It allocates memory as a number of elements of a given size, and
It initializes the memory that is allocated so that all bits are
zero.
malloc() and calloc() are functions from the C standard library that allow dynamic memory allocation, meaning that they both allow memory allocation during runtime.
Their prototypes are as follows:
void *malloc( size_t n);
void *calloc( size_t n, size_t t)
There are mainly two differences between the two:
Behavior: malloc() allocates a memory block, without initializing it, and reading the contents from this block will result in garbage values. calloc(), on the other hand, allocates a memory block and initializes it to zeros, and obviously reading the content of this block will result in zeros.
Syntax: malloc() takes 1 argument (the size to be allocated), and calloc() takes two arguments (number of blocks to be allocated and size of each block).
The return value from both is a pointer to the allocated block of memory, if successful. Otherwise, NULL will be returned indicating the memory allocation failure.
Example:
int *arr;
// allocate memory for 10 integers with garbage values
arr = (int *)malloc(10 * sizeof(int));
// allocate memory for 10 integers and sets all of them to 0
arr = (int *)calloc(10, sizeof(int));
The same functionality as calloc() can be achieved using malloc() and memset():
// allocate memory for 10 integers with garbage values
arr= (int *)malloc(10 * sizeof(int));
// set all of them to 0
memset(arr, 0, 10 * sizeof(int));
Note that malloc() is preferably used over calloc() since it's faster. If zero-initializing the values is wanted, use calloc() instead.
A difference not yet mentioned: size limit
void *malloc(size_t size) can only allocate up to SIZE_MAX.
void *calloc(size_t nmemb, size_t size); can allocate up about SIZE_MAX*SIZE_MAX.
This ability is not often used in many platforms with linear addressing. Such systems limit calloc() with nmemb * size <= SIZE_MAX.
Consider a type of 512 bytes called disk_sector and code wants to use lots of sectors. Here, code can only use up to SIZE_MAX/sizeof disk_sector sectors.
size_t count = SIZE_MAX/sizeof disk_sector;
disk_sector *p = malloc(count * sizeof *p);
Consider the following which allows an even larger allocation.
size_t count = something_in_the_range(SIZE_MAX/sizeof disk_sector + 1, SIZE_MAX)
disk_sector *p = calloc(count, sizeof *p);
Now if such a system can supply such a large allocation is another matter. Most today will not. Yet it has occurred for many years when SIZE_MAX was 65535. Given Moore's law, suspect this will be occurring about 2030 with certain memory models with SIZE_MAX == 4294967295 and memory pools in the 100 of GBytes.
Both malloc and calloc allocate memory, but calloc initialises all the bits to zero whereas malloc doesn't.
Calloc could be said to be equivalent to malloc + memset with 0 (where memset sets the specified bits of memory to zero).
So if initialization to zero is not necessary, then using malloc could be faster.
Related
This question already has answers here:
How malloc works? [duplicate]
(8 answers)
Closed 5 years ago.
int* ptr;
ptr=(int*)malloc(sizeof(int)); //(A)
ptr=(int*)malloc(5*sizeof(int)); //(B)
At line (A), a block of 4 byte is going to create dynamically. Now that's fine. But my question is at line B is it going to create a single 20(5*4) byte block? Or 5 separate blocks of size 4 byte? If it creates a separate block then will they be contiguous? Is ptr=(int*)malloc(5*sizeof(int)); and ptr=(int*)calloc(5,sizeof(int)); equivalent?
They are practically equivalent. malloc will allocate contiguous block.
Difference is that calloc does zero initialization of the memory, while malloc doesn't.
Of course, we are talking about virtual memory. The block will be contiguous for your program. It can be not in physical memory. But it is not important in most cases, until you do not try to do kernel modules or drivers, which work in ring 0. But it is the different story.
But my question is at line B is it going to create a single 20(5*4) byte block?
ptr = malloc(5*sizeof(int)) will allocate 5*sizeof(int) bytes of space. Yes allocated space will be contiguous, if contiguous space is not available then allocation will fail.
Is ptr=(int*)malloc(5*sizeof(int)); and ptr=(int*)calloc(5,sizeof(int)); equivalent?
They are equivalent except that calloc sets the allocated memory to 0.
NOTE: In C, you should not cast the return value of malloc, calloc and realloc.
malloc() tries to allocate the size of memory that you asked for. The function doesn't know how the parameter is transferred, but rather it's value alone.
For example, if sizeof(int) is 4, then:
int* ptr = malloc(sizeof(int) * 5);
and
int* ptr = malloc(20);
are essentially the same. In both the function will get a value of 20 as a parameter. The same will happen if you call malloc like this:
size_t a = 20;
int* ptr = malloc(a);
Therefore, if it succeeds (i.e. doesn't return NULL), it will allocate a contiguous block of memory, with at least the size that you asked for.
All that is true regarding to virtual memory. Meaning, you'll access the memory with a continuous index. Physical memory depends on the way the OS manages you're memory.
If, for example, your OS holds memory page frames (blocks of physical memory) in size of 4kb only, and you ask in malloc for more, although your virtual memory will be contiguous, physical memory might not.
All of that has to do with a wider subject that is called memory management. You can read about the way that linux chose to deal with it here.
Malloc takes requested size of block to be allocated, expressed in bytes. It does not (and cannot, really) determine how you got a given number i.e. if the size is 5*sizeof(int) as in your example or it's 20 or 30-10. It's going to allocate a single block of 20 bytes in either case (assuming size of int is 4 bytes).
Yes it does. malloc will allocate contiguous block, or malloc will fail if there isn't a large enough contiguous block available. (A failure with malloc will return a NULL pointer.)
Malloc and Calloc both allocate the memory but calloc initialise to zero while malloc does not.
First of all, it's bad to cast the return value of malloc(). This function takes as input the number of bytes that you want to allocate. It doesn't matter whether you pass (5*sizeof(int)) or 20 (assuming an int is 4 bytes on your machine). A chunk with the given number of bytes will be allocated. When I say chunk, I mean that you can access each byte like this:
char *ptr = malloc(5*sizeof(int));
ptr++; // now ptr points to the second byte of the chunk.
Or, you could do something like this:
int *ptr = malloc(5*sizeof(int));
ptr++; // now ptr points to the second element (that's sizeof (int) bytes away) from the start of the chunk.
Is ptr=(int*)malloc(5*sizeof(int)); and
ptr=(int*)calloc(5,sizeof(int)); equivalent?
When using malloc, you should not assume anything about the contents of the chunk of memory. When you use calloc all the bytes in the chunk is guaranteed to be set to 0. malloc might be faster than calloc on some implementations. Other than that there is no difference.
I am reading about pointers and dynamic memory allocation in C. I have found that the function calloc() is similar to malloc() but the former does initialize memory to 0.
I do not understand why does it mean to initialize memory to zero?
NOTE: I am not asking the difference between malloc and calloc, but the meaning of initializing memory to zero.
Thanks in advance.
p = calloc(12, 1024);
Is roughly equivalent to:
p = malloc(12 * 1024);
if (p != NULL)
memset(p, 0, 12 * 1024);
So calloc does two things that malloc does not:
It multiplies the nmemb and size variables to calculate the total size of the allocation
It sets every byte of the allocation to zero
For this purpose, calloc is good for allocating arrays, particular arrays of scalar values.
There are cases where this initialization is undesirable:
Initialization to all-zero bits is insufficient for pointers, where NULL may not be all zeros.
If you're going to use the allocation as a buffer and will be reading data into it, then it's a waste of time to initialize it to all-zeros first.
The memory block returned by malloc() contains whatever data happened to be in that memory; it contains leftovers of the previous usage of that memory.
Before returning, calloc() sets to 0 all the bytes of the memory block it returns.
Every object has an underlying representation as a sequence of bytes in memory. It is those bytes that have value zero when they are obtained via calloc. What that means for particular objects depends on how they are represented in memory. For example, uint16_t is guaranteed to occupy 16 bits without padding, and the representation bits make up its value, so *(uint16_t*) calloc(sizeof(uint16_t), 1) is the object that holds value zero. By contrast, if you obtain the memory via malloc, you must not attempt to read from it, but rather you must assign a value to it first.
When you allocate memory, you are issuing a request to your operating system to reserve a block of memory for your program's use. Simply reserving the memory doesn't necessarily mean that whatever data was in the memory already will be initialized.
Memory that's initialized to zero is memory in which every addressable object (every byte), will always have a value equal to zero, when you read it as an non-padded type (e.g. unsigned char),
It's useful in the sense that you always get the same memory contents (instead of "random" garbage). This eliminates the possibility that this memory chunk could have acted as a potential source of non-deterministic behavior of your program. Deterministic behavior helps you catch errors earlier.
It just means that all bits will be set to zero after reserving that memory block. What the consequence is depends on your interpretation of the data. For example, If you cast these to memory addresses/pointers, they'll be equivalent to NULL. If you cast them to some integer type, they'll be equivalent to zero valued integers.
Whether you want to use malloc() and keep garbage values (so just reserve memory without modifying its values from previous time) or use calloc() to get a clean memory block depends on what you're planning to do with this memory block. Normally the cost to set all memory values to zero is negligible when talking about normal software, but if you're developing an extremely high performance software, then every bit matters, and you have the freedom to use these this memory with or without setting it to zero.
As #Blorgbeard says in one comment. I just means that every byte in the block you are allocating is going to be set to 0x00.
From what I understand, the malloc function takes a variable and allocates memory as asked. In this case, it will ask the compiler to prepare memory in order to fit the equivalence of twenty double variables. Is my way of understanding it correctly, and why must it be used?
double *q;
q=(double *)malloc(20*sizeof(double));
for (i=0;i<20; i++)
{
*(q+i)= (double) rand();
}
You don't have to use malloc() when:
The size is known at compile time, as in your example.
You are using C99 or C2011 with VLA (variable length array) support.
Note that malloc() allocates memory at runtime, not at compile time. The compiler is only involved to the extent that it ensures the correct function is called; it is malloc() that does the allocation.
Your example mentions 'equivalence of ten integers'. It is very seldom that 20 double occupy the same space as 10 int. Usually, 10 double will occupy the same space as 20 int (when sizeof(int) == 4 and sizeof(double) == 8, which is a very commonly found setting).
It's used to allocate memory at run-time rather than compile-time. So if your data arrays are based on some sort of input from the user, database, file, etc. then malloc must be used once the desired size is known.
The variable q is a pointer, meaning it stores an address in memory. malloc is asking the system to create a section of memory and return the address of that section of memory, which is stored in q. So q points to the starting location of the memory you requested.
Care must be taken not to alter q unintentionally. For instance, if you did:
q = (double *)malloc(20*sizeof(double));
q = (double *)malloc(10*sizeof(double));
you will lose access to the first section of 20 double's and introduce a memory leak.
When you use malloc you are asking the system "Hey, I want this many bytes of memory" and then he will either say "Sorry, I'm all out" or "Ok! Here is an address to the memory you wanted. Don't lose it".
It's generally a good idea to put big datasets in the heap (where malloc gets your memory from) and a pointer to that memory on the stack (where code execution takes place). This becomes more important on embedded platforms where you have limited memory. You have to decide how you want to divvy up the physical memory between the stack and heap. Too much stack and you can't dynamically allocate much memory. Too little stack and you can function call your way right out of it (also known as a stack overflow :P)
As the others said, malloc is used to allocate memory. It is important to note that malloc will allocate memory from the heap, and thus the memory is persistent until it is free'd. Otherwise, without malloc, declaring something like double vals[20] will allocate memory on the stack. When you exit the function, that memory is popped off of the stack.
So for example, say you are in a function and you don't care about the persistence of values. Then the following would be suitable:
void some_function() {
double vals[20];
for(int i = 0; i < 20; i++) {
vals[i] = (double)rand();
}
}
Now if you have some global structure or something that stores data, that has a lifetime longer than that of just the function, then using malloc to allocate that memory from the heap is required (alternatively, you can declare it as a global variable, and the memory will be preallocated for you).
In you example, you could have declared double q[20]; without the malloc and it would work.
malloc is a standard way to get dynamically allocated memory (malloc is often built above low-level memory acquisition primitives like mmap on Linux).
You want to get dynamically allocated memory resources, notably when the size of the allocated thing (here, your q pointer) depends upon runtime parameters (e.g. depends upon input). The bad alternative would be to allocate all statically, but then the static size of your data is a strong built-in limitation, and you don't like that.
Dynamic resource allocation enables you to run the same program on a cheap tablet (with half a gigabyte of RAM) and an expensive super-computer (with terabytes of RAM). You can allocate different size of data.
Don't forget to test the result of malloc; it can fail by returning NULL. At the very least, code:
int* q = malloc (10*sizeof(int));
if (!q) {
perror("q allocation failed");
exit(EXIT_FAILURE);
};
and always initialize malloc-ed memory (you could prefer using calloc which zeroes the allocated memory).
Don't forget to later free the malloc-ed memory. On Linux, learn about using valgrind. Be scared of memory leaks and dangling pointers. Recognize that the liveness of some data is a non-modular property of the entire program. Read about garbage collection!, and consider perhaps using Boehm's conservative garbage collector (by calling GC_malloc instead of malloc).
You use malloc() to allocate memory dynamically in C. (Allocate the memory at the run time)
You use it because sometimes you don't know how much memory you'll use when you write your program.
You don't have to use it when you know thow many elements the array will hold at compile time.
Another important thing to notice that if you want to return an array from a function, you will want to return an array which was not defined inside the function on the stack. Instead, you'll want to dynamically allocate an array (on the heap) and return a pointer to this block:
int *returnArray(int n)
{
int i;
int *arr = (int *)malloc(sizeof(int) * n);
if (arr == NULL)
{
return NULL;
}
//...
//fill the array or manipulate it
//...
return arr; //return the pointer
}
I am trying to free dynamically allocated memory using free(), but I found that what it does is to have the argument pointer point to some new location, and leaving the previously-pointed-at location as it was, the memory is not cleared. And if I use malloc again, the pointer may point to this messy block, and it's already filled with garbage, which is really annoying..
I'm kinda new to C and I think delete[] in c++ doesn't have this problem. Any advise?
Thanks
By free the memory is just released from use. It is released from being allocated to you. it is not explicitly cleared. Some old contents might be present at those memory locations.
To avoid this, there are two solutions.
Solution 1:
You will need to do a memset after allocating memory using malloc.
Code Example:
unsigned int len = 20; // len is the length of boo
char* bar = 0;
bar= (char *)malloc(len);
memset(bar, 0, len);
Solution 2:
Or use, calloc() which initiliazes memory to 0 by default.
Code Example:
int *pData = 0;
int i = 10;
pData = (int*) calloc (i,sizeof(int));
I think delete[] in c++ doesn't have this problem.
No
It behaves exactly this same way. Unless you explicitly set the pointer to 0 the delete'd pointer will not be pointing to 0. So do always set the pointer to 0 after you delete it.
When should you use malloc over calloc or vice versa?
Since calloc sets the allocated memory to 0 this may take a little time, so you may probably want to use malloc() if that performance is an issue.(Ofcourse One most profile their usage to see if this really is a problem)
If initializing the memory is more important, use calloc() as it does that explicitly for you.
Also, some OS like Linux have an Lazy Allocation memory model wherein the returned memory address is a virtual address and the actual allocation only happens at run-time. The OS assumes that it will be able to provide this allocation at Run-Time.
The memory allocated by malloc is not backed by real memory until the program actually touches it.
While, since calloc initializes the memory to 0 you can be assured that the OS has already backed the allocation with actual RAM (or swap).
How about realloc?
Yes, similar behavior to malloc.
Excerpt From the documentation:
void * realloc ( void * ptr, size_t size );
Reallocate memory block
The size of the memory block pointed to by the ptr parameter is changed to the size bytes, expanding or reducing the amount of memory available in the block.
The function may move the memory block to a new location, in which case the new location is returned. The content of the memory block is preserved up to the lesser of the new and old sizes, even if the block is moved.If the new size is larger, the value of the newly allocated portion is indeterminate.
In case that ptr is NULL, the function behaves exactly as malloc, assigning a new block of size bytes and returning a pointer to the beginning of it.
In case that the size is 0, the memory previously allocated in ptr is deallocated as if a call to free was made, and a NULL pointer is returned.
You can use calloc( ) instead of malloc( ) to clear the allocated memory to zero.
Why is having newly allocated memory filled with garbage "really annoying"? If you allocate memory, presumably it's because you're going to use it for something -- which means you have to store some meaningful value into it before attempting to read it. In most cases, in well-written code, there's no reason to care what's in newly allocated memory.
If you happen to have a requirement for a newly allocated block of memory you can call memset after calling malloc, or you can use calloc instead of malloc. But consider carefully whether there's any real advantage in doing so. If you're actually going to use those all-bits-zero values (i.e., if all-bits-zero happens to be the "meaningful value" I mentioned above), go ahead and clear the block. (But keep in mind that the language doesn't guarantee that either a null pointer or a floating-point 0.0 is represented as all-bits-zero, though it is in most implementations they are.)
And free() doesn't "have the argument pointer point to some new location". free(ptr) causes the memory pointed to by ptr to be made available for future allocation. It doesn't change the contents of the pointer object ptr itself (though the address stored in ptr does become invalid).
What is the difference between doing:
ptr = malloc(MAXELEMS * sizeof(char *));
And:
ptr = calloc(MAXELEMS, sizeof(char*));
When is it a good idea to use calloc over malloc or vice versa?
calloc() gives you a zero-initialized buffer, while malloc() leaves the memory uninitialized.
For large allocations, most calloc implementations under mainstream OSes will get known-zeroed pages from the OS (e.g. via POSIX mmap(MAP_ANONYMOUS) or Windows VirtualAlloc) so it doesn't need to write them in user-space. This is how normal malloc gets more pages from the OS as well; calloc just takes advantage of the OS's guarantee.
This means calloc memory can still be "clean" and lazily-allocated, and copy-on-write mapped to a system-wide shared physical page of zeros. (Assuming a system with virtual memory.) The effects are visible with performance experiments on Linux, for example.
Some compilers even can optimize malloc + memset(0) into calloc for you, but it's best to just use calloc in the source if you want zeroed memory. (Or if you were trying to pre-fault it to avoid page faults later, that optimization will defeat your attempt.)
If you aren't going to ever read memory before writing it, use malloc so it can (potentially) give you dirty memory from its internal free list instead of getting new pages from the OS. (Or instead of zeroing a block of memory on the free list for a small allocation).
Embedded implementations of calloc may leave it up to calloc itself to zero memory if there's no OS, or it's not a fancy multi-user OS that zeros pages to stop information leaks between processes.
On embedded Linux, malloc could mmap(MAP_UNINITIALIZED|MAP_ANONYMOUS), which is only enabled for some embedded kernels because it's insecure on a multi-user system.
A less known difference is that in operating systems with optimistic memory allocation, like Linux, the pointer returned by malloc isn't backed by real memory until the program actually touches it.
calloc does indeed touch the memory (it writes zeroes on it) and thus you'll be sure the OS is backing the allocation with actual RAM (or swap). This is also why it is slower than malloc (not only does it have to zero it, the OS must also find a suitable memory area by possibly swapping out other processes)
See for instance this SO question for further discussion about the behavior of malloc
One often-overlooked advantage of calloc is that (conformant implementations of) it will help protect you against integer overflow vulnerabilities. Compare:
size_t count = get_int32(file);
struct foo *bar = malloc(count * sizeof *bar);
vs.
size_t count = get_int32(file);
struct foo *bar = calloc(count, sizeof *bar);
The former could result in a tiny allocation and subsequent buffer overflows, if count is greater than SIZE_MAX/sizeof *bar. The latter will automatically fail in this case since an object that large cannot be created.
Of course you may have to be on the lookout for non-conformant implementations which simply ignore the possibility of overflow... If this is a concern on platforms you target, you'll have to do a manual test for overflow anyway.
The documentation makes the calloc look like malloc, which just does zero-initialize the memory; this is not the primary difference! The idea of calloc is to abstract copy-on-write semantics for memory allocation. When you allocate memory with calloc it all maps to same physical page which is initialized to zero. When any of the pages of the allocated memory is written into a physical page is allocated. This is often used to make HUGE hash tables, for example since the parts of hash which are empty aren't backed by any extra memory (pages); they happily point to the single zero-initialized page, which can be even shared between processes.
Any write to virtual address is mapped to a page, if that page is the zero-page, another physical page is allocated, the zero page is copied there and the control flow is returned to the client process. This works same way memory mapped files, virtual memory, etc. work.. it uses paging.
Here is one optimization story about the topic:
http://blogs.fau.de/hager/2007/05/08/benchmarking-fun-with-calloc-and-zero-pages/
There's no difference in the size of the memory block allocated. calloc just fills the memory block with physical all-zero-bits pattern. In practice it is often assumed that the objects located in the memory block allocated with calloc have initilial value as if they were initialized with literal 0, i.e. integers should have value of 0, floating-point variables - value of 0.0, pointers - the appropriate null-pointer value, and so on.
From the pedantic point of view though, calloc (as well as memset(..., 0, ...)) is only guaranteed to properly initialize (with zeroes) objects of type unsigned char. Everything else is not guaranteed to be properly initialized and may contain so called trap representation, which causes undefined behavior. In other words, for any type other than unsigned char the aforementioned all-zero-bits patterm might represent an illegal value, trap representation.
Later, in one of the Technical Corrigenda to C99 standard, the behavior was defined for all integer types (which makes sense). I.e. formally, in the current C language you can initialize only integer types with calloc (and memset(..., 0, ...)). Using it to initialize anything else in general case leads to undefined behavior, from the point of view of C language.
In practice, calloc works, as we all know :), but whether you'd want to use it (considering the above) is up to you. I personally prefer to avoid it completely, use malloc instead and perform my own initialization.
Finally, another important detail is that calloc is required to calculate the final block size internally, by multiplying element size by number of elements. While doing that, calloc must watch for possible arithmetic overflow. It will result in unsuccessful allocation (null pointer) if the requested block size cannot be correctly calculated. Meanwhile, your malloc version makes no attempt to watch for overflow. It will allocate some "unpredictable" amount of memory in case overflow happens.
from an article Benchmarking fun with calloc() and zero pages on Georg Hager's Blog
When allocating memory using calloc(), the amount of memory requested is not allocated right away. Instead, all pages that belong to the memory block are connected to a single page containing all zeroes by some MMU magic (links below). If such pages are only read (which was true for arrays b, c and d in the original version of the benchmark), the data is provided from the single zero page, which – of course – fits into cache. So much for memory-bound loop kernels. If a page gets written to (no matter how), a fault occurs, the “real” page is mapped and the zero page is copied to memory. This is called copy-on-write, a well-known optimization approach (that I even have taught multiple times in my C++ lectures). After that, the zero-read trick does not work any more for that page and this is why performance was so much lower after inserting the – supposedly redundant – init loop.
Number of blocks:
malloc() assigns single block of requested memory,
calloc() assigns multiple blocks of the requested memory
Initialization:
malloc() - doesn't clear and initialize the allocated memory.
calloc() - initializes the allocated memory by zero.
Speed:
malloc() is fast.
calloc() is slower than malloc().
Arguments & Syntax:
malloc() takes 1 argument:
bytes
The number of bytes to be allocated
calloc() takes 2 arguments:
length
the number of blocks of memory to be allocated
bytes
the number of bytes to be allocated at each block of memory
void *malloc(size_t bytes);
void *calloc(size_t length, size_t bytes);
Manner of memory Allocation:
The malloc function assigns memory of the desired 'size' from the available heap.
The calloc function assigns memory that is the size of what’s equal to ‘num *size’.
Meaning on name:
The name malloc means "memory allocation".
The name calloc means "contiguous allocation".
calloc is generally malloc+memset to 0
It is generally slightly better to use malloc+memset explicitly, especially when you are doing something like:
ptr=malloc(sizeof(Item));
memset(ptr, 0, sizeof(Item));
That is better because sizeof(Item) is know to the compiler at compile time and the compiler will in most cases replace it with the best possible instructions to zero memory. On the other hand if memset is happening in calloc, the parameter size of the allocation is not compiled in in the calloc code and real memset is often called, which would typically contain code to do byte-by-byte fill up until long boundary, than cycle to fill up memory in sizeof(long) chunks and finally byte-by-byte fill up of the remaining space. Even if the allocator is smart enough to call some aligned_memset it will still be a generic loop.
One notable exception would be when you are doing malloc/calloc of a very large chunk of memory (some power_of_two kilobytes) in which case allocation may be done directly from kernel. As OS kernels will typically zero out all memory they give away for security reasons, smart enough calloc might just return it withoud additional zeroing. Again - if you are just allocating something you know is small, you may be better off with malloc+memset performance-wise.
There are two differences.
First, is in the number of arguments. malloc() takes a single argument (memory required in bytes), while calloc() needs two arguments.
Secondly, malloc() does not initialize the memory allocated, while calloc() initializes the allocated memory to ZERO.
calloc() allocates a memory area, the length will be the product of its parameters. calloc fills the memory with ZERO's and returns a pointer to first byte. If it fails to locate enough space it returns a NULL pointer.
Syntax: ptr_var = calloc(no_of_blocks, size_of_each_block);
i.e. ptr_var = calloc(n, s);
malloc() allocates a single block of memory of REQUSTED SIZE and returns a pointer to first byte. If it fails to locate requsted amount of memory it returns a null pointer.
Syntax: ptr_var = malloc(Size_in_bytes);
The malloc() function take one argument, which is the number of bytes to allocate, while the calloc() function takes two arguments, one being the number of elements, and the other being the number of bytes to allocate for each of those elements. Also, calloc() initializes the allocated space to zeroes, while malloc() does not.
Difference 1:
malloc() usually allocates the memory block and it is initialized memory segment.
calloc() allocates the memory block and initialize all the memory block to 0.
Difference 2:
If you consider malloc() syntax, it will take only 1 argument. Consider the following example below:
data_type ptr = (cast_type *)malloc( sizeof(data_type)*no_of_blocks );
Ex: If you want to allocate 10 block of memory for int type,
int *ptr = (int *) malloc(sizeof(int) * 10 );
If you consider calloc() syntax, it will take 2 arguments. Consider the following example below:
data_type ptr = (cast_type *)calloc(no_of_blocks, (sizeof(data_type)));
Ex: if you want to allocate 10 blocks of memory for int type and Initialize all that to ZERO,
int *ptr = (int *) calloc(10, (sizeof(int)));
Similarity:
Both malloc() and calloc() will return void* by default if they are not type casted .!
The calloc() function that is declared in the <stdlib.h> header offers a couple of advantages over the malloc() function.
It allocates memory as a number of elements of a given size, and
It initializes the memory that is allocated so that all bits are
zero.
malloc() and calloc() are functions from the C standard library that allow dynamic memory allocation, meaning that they both allow memory allocation during runtime.
Their prototypes are as follows:
void *malloc( size_t n);
void *calloc( size_t n, size_t t)
There are mainly two differences between the two:
Behavior: malloc() allocates a memory block, without initializing it, and reading the contents from this block will result in garbage values. calloc(), on the other hand, allocates a memory block and initializes it to zeros, and obviously reading the content of this block will result in zeros.
Syntax: malloc() takes 1 argument (the size to be allocated), and calloc() takes two arguments (number of blocks to be allocated and size of each block).
The return value from both is a pointer to the allocated block of memory, if successful. Otherwise, NULL will be returned indicating the memory allocation failure.
Example:
int *arr;
// allocate memory for 10 integers with garbage values
arr = (int *)malloc(10 * sizeof(int));
// allocate memory for 10 integers and sets all of them to 0
arr = (int *)calloc(10, sizeof(int));
The same functionality as calloc() can be achieved using malloc() and memset():
// allocate memory for 10 integers with garbage values
arr= (int *)malloc(10 * sizeof(int));
// set all of them to 0
memset(arr, 0, 10 * sizeof(int));
Note that malloc() is preferably used over calloc() since it's faster. If zero-initializing the values is wanted, use calloc() instead.
A difference not yet mentioned: size limit
void *malloc(size_t size) can only allocate up to SIZE_MAX.
void *calloc(size_t nmemb, size_t size); can allocate up about SIZE_MAX*SIZE_MAX.
This ability is not often used in many platforms with linear addressing. Such systems limit calloc() with nmemb * size <= SIZE_MAX.
Consider a type of 512 bytes called disk_sector and code wants to use lots of sectors. Here, code can only use up to SIZE_MAX/sizeof disk_sector sectors.
size_t count = SIZE_MAX/sizeof disk_sector;
disk_sector *p = malloc(count * sizeof *p);
Consider the following which allows an even larger allocation.
size_t count = something_in_the_range(SIZE_MAX/sizeof disk_sector + 1, SIZE_MAX)
disk_sector *p = calloc(count, sizeof *p);
Now if such a system can supply such a large allocation is another matter. Most today will not. Yet it has occurred for many years when SIZE_MAX was 65535. Given Moore's law, suspect this will be occurring about 2030 with certain memory models with SIZE_MAX == 4294967295 and memory pools in the 100 of GBytes.
Both malloc and calloc allocate memory, but calloc initialises all the bits to zero whereas malloc doesn't.
Calloc could be said to be equivalent to malloc + memset with 0 (where memset sets the specified bits of memory to zero).
So if initialization to zero is not necessary, then using malloc could be faster.