45

I'm a beginner C programmer, and I assumed that this would be the case, but would like some affirmation if possible.

If they are the same, why not just take one argument instead?

Ali
  • 1,014
  • 2
  • 12
  • 17
  • Possible duplicate of [What is the difference between calloc(10,4) and calloc(1,40)?](https://stackoverflow.com/questions/19021266/what-is-the-difference-between-calloc10-4-and-calloc1-40) – S.S. Anne Sep 19 '19 at 13:10
  • @S.S.Anne That is a newer question – palapapa Oct 27 '22 at 08:45
  • 1
    @palapapa which of two dupes should become canonical should be determined by quality, not newness. In this case, though, this thread is probably better. See also [Two arguments to calloc](https://stackoverflow.com/questions/4083916/two-arguments-to-calloc?noredirect=1&lq=1) regarding OP's "why?" question. – ggorlen May 11 '23 at 01:20

7 Answers7

27

There is no real difference between calloc(a, b) and calloc(b, a), despite - they both allocate the same amount of space and fill it appropriately. Alignment of elements within the block don't enter into it, no padding is needed because you're explicitly stating what the "size" of the thing is (any padding would be controlled by using sizeof in the second argument.

In terms of why you would use calloc rather than malloc, people often use allocation routines to allocate space for a set number of items, so calloc() allows that to be specified nicely. So, for example, if you want space for 100 integers or 20 of your own structure:

int *pInt = calloc (100, sizeof(int));
tMyStruct *pMyStruct = calloc (20, sizeof(tMyStruct));

This code actually looks slightly "nicer" than the equivalent malloc() calls:

int *pInt = malloc (100 * sizeof(int));
tMyStruct *pMyStruct = malloc (20 * sizeof(tMyStruct));

although, to seasoned C coders, there's no real distinction (other than the zero initialization of course).

I have to say I have never used calloc in the wild, since I'm almost always creating a struct where zero's don't make sense. I prefer to initialize all the fields manually to ensure I get the values I want.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
19

To the excellent responses posted, I want to add one more point of difference between using calloc(nelem, elsize) versus malloc(nelem * elsize): quality implementations of calloc will ensure that if your nelem and elsize were big enough to cause an integer overflow when multiplied together, it will fail rather than cause an undersized allocation, as a naive malloc invocation would.

Just this feature alone would be enough for me to prefer calloc to malloc. Background reading.

C. K. Young
  • 219,335
  • 46
  • 382
  • 435
12

calloc(4, 6) and calloc(6, 4) are NOT the same:

On a typical 32bit/64bit system, the first would allocate 32 bytes and the second 24 bytes.


void *calloc(size_t nelem, size_t elsize);

The key point is that calloc must return the memory as if it was correctly aligned as an array. It is meant to allocate an array and be used as follows:

A *p = (A*)calloc(count, sizeof(A));
for (int i = 0; i < count; ++i)
{
    f(&(p[i]));
    // f(p + i) is also valid
}

or

A *p = (A*)calloc(count, sizeof(A));
for (A *q = p; q != p + count; ++q)
{
    f(q);
}

calloc is supposed to allocate the array taking into account padding and other operating requirements of the target system. So on most 32bit machines, where a 6 byte structure would need to be padded to 8 bytes, it would allocate 4 lots of 8 bytes.

calloc where the first argument is a sizeof() is most likely a bug and should be investigated.

calloc where the second argument is not sizeof(atype) is undefined. It reeks of hidden assumptions and is dangerous to port.

Clarification: On a typical 32bit/64bit system, a structure is likely to be padded and aligned to a multiple of 32bits. As such on these systems sizeof would not return 6 bytes. In fact there is no guarantee that the compiler would not pad and align to some multiple of 16 bytes if that is what the compiler/platform requires.

My answer is based on the fact you should not make assumptions about structure size. They can change with compiler options, or target platform. Just make sure that your second argument is a sizeof expression and don't make assumptions.


From the standard:

The calloc() function shall allocate unused space for an array of nelem elements each of whose size in bytes is elsize. The space shall be initialized to all bits 0.

The pointer returned if the allocation succeeds shall be suitably aligned so that it may be assigned to a pointer to any type of object and then used to access such an object or an array of such objects in the space allocated (until the space is explicitly freed or reallocated). Each such allocation shall yield a pointer to an object disjoint from any other object. The pointer returned shall point to the start (lowest byte address) of the allocated space.

Community
  • 1
  • 1
mat_geek
  • 2,481
  • 3
  • 24
  • 29
  • Most programmers I have worked with assume they are the same. One project wrote a custom allocator with that assumption. When it was proven wrong, the team lead decided to fix it by adding a comment stating the second argument must be a sizeof or it'll cause a crash. – mat_geek Feb 02 '09 at 01:11
  • 11
    i believe you are wrong. both malloc and calloc must return a pointer suitable aligned for any object type. as it happens, that's also exactly what you have quoted there from the standard. assuming my believing is wrong, can you provide a link for further reading about this please? – Johannes Schaub - litb Feb 02 '09 at 01:13
  • 1
    anyway, if you change the order of the arguments, you never are guaranteed for any function whatsoever that exactly the same happens. implementations could do optimizations on their behalf always - as soon as the constraints put by the standard are not violated so that using code fails to work. – Johannes Schaub - litb Feb 02 '09 at 01:15
  • 6
    I agree with litb; this is an interesting theory, but not correct. The sizeof() operator deals with alignment issues in arrays. If sizeof() returns 6, then the type can be allocated at successive 6 byte slots; if it couldn't (because of an alignment restriction on a float), then sizeof() says 8... – Jonathan Leffler Feb 02 '09 at 01:28
  • i so hate it that we can't edit comments in place :) anyway - s,as soon,as long, :) and thanks Jonathan that's exactly what i mean. padding at the end of the struct deals with aligning issues for elements so they can be put next after each other. – Johannes Schaub - litb Feb 02 '09 at 01:32
  • 1
    `calloc()` need not factor in alignment of objects within the array. As Jonathan mentions - that's taken into account by the sizeof() the object. If an implementation did do something like that, it would just end up reserving more memory than needed. If you depend on that behavior, you have a bug. – Michael Burr Feb 02 '09 at 03:49
  • 6
    -1 The reasoning that `calloc(4, 6)` might round up 6 to 8 is completely wrong. Even on 64bit systems you can easily have `sizeof foo` being 6, e.g. for `char foo[6];` and `calloc (4,6)` is required to give you memory that can be treated as a `char bar[4][6]`. – Jens May 18 '12 at 15:28
  • 2
    @Joh That means that http://en.cppreference.com/w/cpp/memory/c/calloc is giving misinformation on calloc() as it states "Due to the alignment requirements, the number of allocated bytes is not necessarily equal to num*size.", doesn't it? – Kaiserludi Feb 12 '15 at 19:07
  • CISC (x86) platforms allow unpadded array members but RISC (like arm) platforms do not. We were bitten by that assumption and it took ages to find because our structure was not a multiple of 32 bits on a RISC platform. – mat_geek Mar 12 '17 at 02:29
  • Downvote, answer is incorrect, as explained in the comments. – jcsahnwaldt Reinstate Monica Dec 18 '21 at 19:47
6

There is a slight distinction: Calloc can decide to zero-out the memory only as it is needed and then there's the advantage of knowing the size of the elements.

I can't name any implementations doing this, but it was thought for this.

As an example:

One callocates 4GB of memory, but the system has only 2GB: it wouldn't make sense to write 2GBs of zero into the virtual memory, therefore the system could set a dirty-flag on this memory to zero it out as it gets loaded into memory.

Georg Schölly
  • 124,188
  • 49
  • 220
  • 267
  • 1
    I'd be surprised if any *real* implementations actually implement `calloc` as a `malloc` and a `memzero` for all but small memory sizes. A very trivial optimization would be to map the page(s) to `/dev/zero`. – sanjoyd Nov 03 '10 at 15:05
  • @theDigtialEngel: I've never seen a calloc implementation from the inside, so I can't tell. – Georg Schölly Nov 03 '10 at 16:59
6

Despite the accepted answer (which I believe to be correct), there seems to be confusions about how many bytes are allocated due to alignment. So here's a little test on my 32-bit Linux with gcc-4.3:

#include <stdio.h>
#include <stdlib.h>

int main()
{
  char* p1 = calloc(6, 4);
  char* p2 = calloc(4, 6);
  char* p3 = calloc(1,1);
  printf("%p, %p, %p\n", p1, p2, p3);
  return 0;
}

The result is:

0x826b008, 0x826b028, 0x826b048

which shows that both calloc(6,4) and calloc(4,6) allocate the same amount of memory, which is rounded to 32 bytes on my system. Changing the numbers to calloc(3,4) and calloc(4,3) will give the following result:

0x95d2008, 0x95d2018, 0x95d2028

which shows that 16 bytes are reserved when 12 are requested and allocated to the program. In either case, both calloc(a,b) and calloc(b,a) calls have the same effect on the memory usage.


Added by Jonathan Leffler because 300 characters is never going to be enough.

Consider this program, which leaks memory like a veritable sieve, but demonstrates a point:

#include <stdlib.h>
#include <stdio.h>

int main()
{
    int i, j, k;

    for (i = 1; i < 17; i++)
        for (j = 1; j < 9; j++)
            for (k = 0; k < 4; k++)
                printf("(%2d,%d)%d: %p\n", i, j, k, calloc(i, j));
    return(0);
}

On Windows, under Cygwin, this starts by allocating blocks that are 16 bytes apart (actually, the second block is 24 bytes after the first, but thereafter, they are 16 bytes apart). When allocating (2,7), the block addresses start incrementing by 24 bytes; likewise, (3,4) allocates blocks 16 bytes apart, but (3,5) allocates blocks 24 bytes apart. And, for the record, both (4,6) and (6,4) return pointers 32 bytes apart.

This simply demonstrates that there is some overhead associated with an allocation call. If you look at the archetypal implementation of malloc() et al in K&R, you will see that the size of the block is stored ahead of the memory that you're entitled to use. Different implementations do these things differently; those worried about memory trampling will avoid storing control data near where the user can wreak havoc.

When you calloc(4,6), you only have reliable access to 24 bytes of data. Even if your implementation gives you return values that are 32 bytes apart, you may not safely use any more than the 24 bytes you requested. And debugging versions of malloc() will observe if you write out of the bounds you requested.

C. K. Young
  • 219,335
  • 46
  • 382
  • 435
PolyThinker
  • 5,152
  • 21
  • 22
  • 2
    That just shows that there is at least 4 bytes of overhead and that allocations are quantized. Each memory allocation normally includes some overhead (for example, the size of the block that was allocated is written just before the returned pointer - details vary by implementation). – Jonathan Leffler Feb 02 '09 at 02:57
  • 1
    Points taken. I guess I didn't state it clearly but I wanted to show that the `effect' of calloc(a,b) and calloc(b,a) is exactly the same. – PolyThinker Feb 02 '09 at 05:23
4

There is another way to look into this question.

GNU C Library defines calloc like this:

void * __libc_calloc (size_t n, size_t elem_size)
{
  // ... (declarations)

  /* size_t is unsigned so the behavior on overflow is defined.  */
  bytes = n * elem_size;
#define HALF_INTERNAL_SIZE_T \
  (((INTERNAL_SIZE_T) 1) << (8 * sizeof (INTERNAL_SIZE_T) / 2))
  if (__builtin_expect ((n | elem_size) >= HALF_INTERNAL_SIZE_T, 0))
    {
      if (elem_size != 0 && bytes / elem_size != n)
        {
          __set_errno (ENOMEM);
          return 0;
        }
    }

  void *(*hook) (size_t, const void *) = atomic_forced_read (__malloc_hook);
  if (__builtin_expect (hook != NULL, 0))
    {
      sz = bytes;
      mem = (*hook)(sz, RETURN_ADDRESS (0));
      if (mem == 0)
        return 0;

      return memset (mem, 0, sz);
    }

  sz = bytes;

  // ...more stuff, but no mention of n & elem_size anymore
}

So, at least in glibc these two calls do have identical effect.

dbrank0
  • 9,026
  • 2
  • 37
  • 55
2

It is the same. The reason is because most of the time you want to use a sizeof operator as one of the arguments. If passing two parameters bother you, call malloc() which has a single argument.

Adrian Frühwirth
  • 42,970
  • 10
  • 60
  • 71
Otávio Décio
  • 73,752
  • 17
  • 161
  • 228
  • 22
    You should note that malloc() won't zero the memory as calloc() does. – Eduard - Gabriel Munteanu Feb 01 '09 at 23:43
  • Well, that is true. Thanks for the heads up. – Otávio Décio Feb 01 '09 at 23:46
  • 1
    Is it true they're the same when you take packing into consideration? Is calloc(16,3) the same as calloc(3,16) on a machine which needs any data element to start on a 4-byte boundary? – ChrisW Feb 01 '09 at 23:47
  • 1
    @ChrisW: Yes, see http://www.opengroup.org/onlinepubs/000095399/functions/calloc.html: "The pointer returned if the allocation succeeds shall be suitably aligned so that it may be assigned to a pointer to any type of object and then used to access such an object or an array of such objects...". – paxdiablo Feb 02 '09 at 00:27
  • Doesn't that implies that the answer is "no: they're not the same"? That on a machine with 4-byte packing, for example, calloc(4,3) would actually allocate 16 bytes, whereas calloc(3,4) would allocate only 12 bytes? – ChrisW Feb 02 '09 at 00:58
  • 2
    ChrisW. calloc has to return a pointer that's suitable aligned for any type of object. that means it will always return a pointer to an address maximally aligned. the order, therefor, won't necessarily be changed because of aligning, at least i don't see any reason why so. – Johannes Schaub - litb Feb 02 '09 at 01:23
  • @ChrisW: calloc gives you the address of an array. The entire array may be aligned but not the individual elements. – PolyThinker Feb 02 '09 at 01:25
  • 1
    and given that an array can't have "holes" between its elements, you will end up having a maximally aligned array starting somewhere and having 4 * 3 == 3 * 4 bytes. so both cases are identically in that regard, i think. – Johannes Schaub - litb Feb 02 '09 at 01:27
  • 1
    I can't give this an upvote until it distinguishes between malloc() not initializing the memory and calloc() initializing the memory. That is crucial - if it wasn't, you'd use malloc() because it doesn't do the initialization. – Jonathan Leffler Feb 02 '09 at 01:38
  • @Jonathan - if you read the question you'll see that it refers solely to calloc. I just said if he wanted to use a single argument, to use malloc. – Otávio Décio Feb 02 '09 at 02:15
  • @ocdecio - Actually I think it could be misleading. Perhaps would be slightly better to say "Use a single argument wrapper on calloc" or "Use malloc followed by memset". Although clearly its not that big a problem. – Ali Feb 02 '09 at 23:00
  • 2
    Using `malloc` over `calloc` is really a bad advice. `calloc` is specifically optimized for delivering zero-filled memory regions. –  Mar 22 '12 at 19:07