I have a small confusion in using calloc over malloc. I remember somewhere I have read that calloc is slower than malloc because calloc performs initialization to zero after performing memory allocation.
In the project I am working, I see that after malloc they are assigning zero to all the values as shown below,
str* strptr = (str*)malloc(sizeof(str));
memset(strptr,0,sizeof(str));
Here str is a structure.
This is similar to
str* strptr =(str*)calloc(1,sizeof(str));
I want to know whether using malloc over calloc has any advantages and which method is preferred.
I want to know whether using malloc over calloc has any advantages
The differences between them are just
calloc also takes object count as opposed to malloc which only takes byte count
calloc zeros memory; malloc leaves the memory uninitialized
So no exceptional advantages except for the zeroing part.
which method is preferred.
Why not use malloc the way its used in the code base you're looking at? To avoid duplication of work and code; when an API already does that why reinvent the wheel? You could have seen code bases with a utility function that does just that: allocate and zero memory. This shows that the snippet will be used many times and hence they wrap it in a macro/function to call it from different places. However, why do it when calloc already does that?
The best code is no code at all. Lesser code is better, and thus you should prefer calloc over malloc here. May be the optimizer would do the same thing underneath, but why take the chance? Apparently, the optimizer may not be that smart, which is the reason for this question: Why malloc+memset is slower than calloc?
Also the calloc route requires lesser key strokes.
Related
I am coding for an embedded system using ARM cross toolchain arm-none-ebi-gcc. Because the code is running freeRTOS which has its own heap memory management so I want to overwrite malloc(), free() and realloc() in the libc and wrap them simply to call the functions in freeRTOS. Only one problme, the freeRTOS does not have realloc(), that's strange, but my code definitely need it. So I want to understand, what will happen if I only overwrite malloc() and free() but still keep the realloc() the version as it be in the libc? Also, I feel providing my own realloc() that just call malloc() with the new size and do the memcopy after the new memory block got allocated looks not safe enough to my mind, because the new size usually larger than the old size in my application, so when I do a memcopy() with a size larger than the actually allocated memory block will could create some pointer access error, it that possible?
Thanks in advance.
-woody
Partially replacing the allocator (replacing some functions but not others) can't work. At worst, you will get serious heap data structure corruption from one implementation interpreting another's data structures as its own. It's possible to harden against this so that things just fail to link or fail to allocate (provide null pointer results) at runtime if this is done, and I did this in musl libc as described in these commits:
https://git.musl-libc.org/cgit/musl/commit/src/malloc?id=c9f415d7ea2dace5bf77f6518b6afc36bb7a5732
https://git.musl-libc.org/cgit/musl/commit/src/malloc?id=618b18c78e33acfe54a4434e91aa57b8e171df89
https://git.musl-libc.org/cgit/musl/commit/src/malloc?id=b4b1e10364c8737a632be61582e05a8d3acf5690
but I doubt many other implementations take the same precautions. And they won't help what you want actually work; they'd just prevent catastrophic results.
If you really need realloc, you're going to have to make a working one for the implementation you're adopting. The easiest way to do that is make it just malloc, memcpy, and free, but indeed you need a way to determine the length argument to pass to memcpy. If you just pass the new length, it might be safe on a microcontroller without MMU, as long as your lengths aren't so large they risk running over into an MMIO range or something. But the right thing to do is read the malloc implementation enough to understand where it's stored the allocated size, and write your own code to extract that. At that point you can write a correct/valid realloc using memcpy.
I was wondering whether calloc() is preferable to a malloc followed by a memset. The latter appears to be the most common way of allocating and initializing memory.
A github code search turns up many calloc test and implementations but in the first number of pages no code actually using calloc.
Does anyone who knows of any projects/organizations that use or recommend using calloc and the circumstances where recommend it?
From the comments and answers below, here's some the thoughts that have emerges so far:
calloc(n, size) can prevent overflow that is possible with malloc(n * size)
combining malloc and memset gives calloc a chance to request a page that is known to already be zeroed.
a disadvantage to calloc that the combined steps may preclude other wrappers around malloc.
Well, I use calloc in quite a bit of C code, so I guess that's an answer. I think the slightly unusual call method (number of elements and size of element) may throw people. However, one other reason why you may not see as many calls as you would expect is that a lot of larger projects use wrappers around malloc, calloc, and friends that do error handling (usually terminating the program) on memory allocation failure. So the actual code uses xcalloc instead.
One reason to use calloc over malloc plus memset is that calloc may be more efficient. If the C library already knows that a page is zeroed (perhaps it just got new zeroed memory from the OS), it doesn't have to explicitly zero it.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
c difference between malloc and calloc
Why does calloc require two parameters and malloc just one?
I've noticed this with many C functions calls particularly ones that deal with memory or file operations, but not all of them use both parameters. For instance malloc is passed one parameter, the size in bytes of the memory space needed. Calloc on the other hand is passed two parameters, the size in bytes of an element and the number of elements (size and nmem). There are other functions that use these size and nmem parameters as well.
Essentially the calloc call would allocate the same amount of memory as calling malloc(nmemsize) so all that's really happening is the asterisk () is replaced with a comma (,). At least this is all I can tell from the higher level that I am working at. I don't see a difference from calling calloc(1, nmemsize), calloc(nmemsize, 1), or calloc(nmem, size).
Is there something actually happening at a lower level that makes calling for instance calloc(1, nmem*size) fundamentally different from calloc(nmem, size)?
Edit: I know the functional difference between calloc and malloc. I'm interested in why there are differences in the parameters. There are other functions that use 2 size parameters for the total size (fread, fwrite, etc). I'm not concerned with the specific functions but rather why there are two parameters for the total size used in the function when essentially the total size becomes the two parameters multiplied together. I find most of the time when I use these functions I use the size that I need in the "size" parameter and a '1' for the "nmem" (sometimes "count" etc.) parameter.
In a comment to the question, I wrote that calloc() allows better memory alignment for platforms where it matters. I haven't been able to find anything to support that (yet). I am pretty sure it was a feature of the VMS/VAXC compiler, but source for that is scarce.
However, I did find that calloc() and alloc() appeared at the same time, with the release of Unix V6 in May 1975. In V5, released 11 months earlier, neither function is present; the kernel and runtime library (and assembler and C compiler) were written in assembly.
In the V6 release, calloc is implemented as the four line source code module:
calloc(n, s)
{
return(alloc(n*s));
}
calloc() does not clear the allocated memory; see alloc(), and there was no man page for calloc() in V6; however the man page for alloc():
DESCRIPTION
Alloc and free provide a simple general-purpose core management package.
Alloc is given a size in bytes; it returns a pointer to an area at least that size which
is even and hence can hold an object of any type. The argument to free
is a pointer to an area previously allocated by alloc; this space is made available for further allocation.
Needless to say, grave disorder will result if the space
assigned by alloc is overrun or if some random number is handed to free.
The routine uses a first-fit algorithm which coalesces blocks being freed with other
blocks already free. It calls sbrk (see "break (II))"
to get more core from the system when there is no suitable space already free.
DIAGNOSTICS
Returns -1 if there is no available core.
BUGS
Allocated memory contains garbage instead of being cleared.
Not even NULL is returned in the case of memory exhaustion!
calloc() first formally appears in UNIX V7, January 1979, along with several other improvements:
calloc() clears the memory returned.
alloc() was renamed to malloc()
realloc() appeared
in the case of memory exhaustion or a heap error, the functions "return a null pointer (0)"
Is there something actually happening at a lower level that makes calling for instance calloc(1, nmem*size) fundamentally different from calloc(nmem, size)?
This attempt to explain things is purely dependent from the libc implementation - and therefore left at the appreciation of a specific libc author:
Since calloc() is zeroing memory, the rationale might have been that it could (potentially) waste some more cycles at doing a mult.
In contrast, malloc() is given a chance to use a precalculated value, potentially reducing the overhead in a call that migh be simpler to satisfy.
Don't forget that C was designed at a time when each CPU cycle was costing a lot - hence a very lean design as compared to many other 'higher-level' languages.
This question could probably be better answered by the author of C Dennis Ritchie.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
c difference between malloc and calloc
Is there any situation where you would prefer malloc over calloc. i know both malloc and calloc allocate memory dynamically and that calloc also initializes all bits in alloted memory to zero.
From this i would guess its always better to use calloc over malloc. Or is there some situations where malloc is better? Performance may be?
If you need the dynamically allocated memory to be zero-initialized then use calloc.
If you don't need the dynamically allocated memory to be zero-initialized, then use malloc.
You don't always need zero-initialized memory; if you don't need the memory zero-initialized, don't pay the cost of initializing it. For example, if you allocate memory and then immediately copy data to fill the allocated memory, there's no reason whatsoever to perform zero-initialization.
calloc and malloc are functions that do different things: use whichever one is most appropriate for the task you need to accomplish.
Relying on calloc's zero-initialisation can be dangerous if you're not careful. Zeroing memory gives 0 for integral types and \0 for char types as expected. But it doesn't necessarily correspond to float/double 0 or NULL pointers.
You're normally allocating memory with the specific intent of storing something there. That means (at least most of) the space that's zero-initialized by calloc will soon be overwritten with other values. As such, most code uses malloc for a bit of extra speed with no real loss.
Nearly the only use I've seen for calloc was code that was (supposedly) benchmarking the speed of Java relative to C++. In the C++ version, it allocated some memory with calloc, then used memset to initialize the memory again in (what seemed to me) a fairly transparent attempt at producing results that favored Java.
I've read with interest the post C difference between malloc and calloc. I'm using malloc in my code and would like to know what difference I'll have using calloc instead.
My present (pseudo)code with malloc:
Scenario 1
int main()
{
allocate large arrays with malloc
INITIALIZE ALL ARRAY ELEMENTS TO ZERO
for loop //say 1000 times
do something and write results to arrays
end for loop
FREE ARRAYS with free command
} //end main
If I use calloc instead of malloc, then I'll have:
Scenario2
int main()
{
for loop //say 1000 times
ALLOCATION OF ARRAYS WITH CALLOC
do something and write results to arrays
FREE ARRAYS with free command
end for loop
} //end main
I have three questions:
Which of the scenarios is more efficient if the arrays are very large?
Which of the scenarios will be more time efficient if the arrays are very large?
In both scenarios,I'm just writing to arrays in the sense that for any given iteration in the for loop, I'm writing each array sequentially from the first element to the last element. The important question: If I'm using malloc as in scenario 1, then is it necessary that I initialize the elements to zero? Say with malloc I have array z = [garbage1, garbage2, garbage 3]. For each iteration, I'm writing elements sequentially i.e. in the first iteration I get z =[some_result, garbage2, garbage3], in the second iteration I get in the first iteration I get z =[some_result, another_result, garbage3] and so on, then do I need specifically to initialize my arrays after malloc?
Assuming the total amount of memory being initialized in your two examples is the same, allocating the memory with calloc() might be faster than allocating the memory with malloc() and then zeroing them out in a separate step, especially if in the malloc() case you zero the elements individually by iterating over them in a loop. A malloc() followed by a memset() will likely be about as fast as calloc().
If you do not care that the array elements are garbage before you actually store the computation results in them, there is no need to actually initialize your arrays after malloc().
For 1 and 2, both do the same thing: allocate and zero, then use the arrays.
For 3, if you don't need to zero the arrays first, then zeroing is unnecessary and not doing it is faster.
There is a possibility that calloc's zeroing is more efficient than the code you write, but this difference will be small compared to the rest of the work the program does. The real savings of calloc is not having to write that code yourself.
Your point stated in 3. seems to indicate a case or unnecessary initialization. That is pretty bad speed wise, not only the time spent doing it is wasted but a whole lot of cache eviction happened because of it.
Doing a memset() or bzero() (that are called by calloc() anyway) is a good way to invalidate huge portion of your cache. Don't do it unless you are sure you won't overwrite everything yet can read parts of the buffer that will not have been written (as if 0 is an acceptable default value). If you write over everything anyway by all mean don't initialize your memory unnecessarily.
Unnecessary memory writing will not only ruin your app performance but also the performance of all applications sharing the same CPU with it.
The calloc and memset approaches should be about the same, and maybe slightly faster than zeroing it yourself.
Regardless, it's all relative to what you do inside your main loop, which could be orders of magnitude larger.
malloc is faster than Calloc because the reason is that malloc return memory as it is from an operating system. But when you will call Calloc it gets memory from the kernel or operating system and its initializes with its zero and then its return to you.
so, the initialization takes time. that's why malloc faster than Calloc
I dont know for linux. But on Windows there is something called the zero-page thread... calloc use those pages already initialized to zero. There is no difference in speed between malloc and calloc.
malloc differ by calloc by two reason
malloc takes one argument whereas calloc takes two argument
malloc is faster than calloc reason is that malloc processed single dimensional array to pointer format whereas calloc takes double dimensional array and before processed it converts to single dimensional array then to pointer format.
I think that, that's why malloc processing faster as compared to calloc