8

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.

Community
  • 1
  • 1
Chris
  • 402
  • 1
  • 5
  • 18
  • 1
    Memory alignment is improved (on platforms where it matters) with the two parameter form. – wallyk Oct 12 '12 at 16:07
  • As for `malloc()` and `calloc()` you find an interessting difference explained here: http://stackoverflow.com/a/1585987/694576 ... - anyway, would you mind pointing us to the other functions, besides the latter two, you have in mind. – alk Oct 12 '12 at 16:12
  • 2
    @Paciv it's not quite a duplicate as that question and its answers do not address the difference in the number of parameters. – Dave Rager Oct 12 '12 at 16:17
  • 2
    @wallyk I'm interested in more information about the alignment issues, care to explain in an answer? – Dave Rager Oct 12 '12 at 16:18
  • @JensGustedt I agree about the duplicate. And the accepted answer on that question has a quite interesting discussion on the topic in the comments. – Dave Rager Oct 12 '12 at 16:41
  • @JensGustedt Thanks. The discussion in that thread only considers the differences between malloc and calloc. It seems to be that the reason for the parameter differences is historical in that memory sizes were a lot smaller and possibly due to different developers. I assume this would be the case for other functions that use 2 size parameters instead of 1 but maybe it depends on the function. – Chris Oct 12 '12 at 17:02

2 Answers2

2

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)"
wallyk
  • 56,922
  • 16
  • 83
  • 148
  • Apologies if I missed something, but how does this answer the question? All I see from the code is that calloc is just a call to alloc but it does the multiplication for you. Is the conclusion that it is just a nicety or that it was just a random implementation detail a developer made up? – kurtzbot Oct 12 '12 at 21:06
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.

Gil
  • 3,279
  • 1
  • 15
  • 25