Is calloc(4, 6) the same as calloc(6, 4)?

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?

-------------Problems Reply------------

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.

People mostly 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.

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

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.

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.

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.

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.

Category:c# Views:0 Time:2009-02-01

Related post

  • Why malloc+memset is slower than calloc? 2010-04-22

    It's known that calloc is different than malloc in that it initializes the memory allocated. With calloc, the memory is set to zero. With malloc, the memory is not cleared. So in everyday work, I regard calloc as malloc+memset. Incidentally, for fun,

  • preferring malloc over calloc 2010-11-22

    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

  • What is the way of correct way in using calloc for an array? 2011-10-02

    I want to create a pointer to an array of pointers (with 10 pointers in the array), then I want to give a pointer a value. This is what I have so far: char **arraypointer = calloc (10, sizeof (char*)); How will I give value to this array? I've tried:

  • Repeated calloc over the same pointer 2011-10-12

    What happens when I use different succesive calloc functions over the same pointer? int *ptr; ptr = (int *) calloc(X, sizeof(int)); ptr = (int *) calloc(Y, sizeof(int)); ptr = (int *) calloc(Z, sizeof(int)); Where X,Y,Z are three distinct values. ---

  • why would freeing calloc'ed memory crash my VC6 project? 2009-03-04

    Compare these two largely identical functions. In the first, the memory for buff is allocated using _alloca. This works fine. In the second, calloc and free are used instead of _alloca. This crashes. The weird thing is that I use the calloc/free tech

  • how can i override malloc(), calloc(), free() etc under OS X? 2009-05-30

    Assuming the latest XCode and GCC, what is the proper way to override the memory allocation functions (I guess operator new/delete as well). The debugging memory allocators are too slow for a game, I just need some basic stats I can do myself with mi

  • Difference between malloc and calloc? 2009-10-08

    What is the difference between doing: ptr = (char **) malloc (MAXELEMS * sizeof(char *)); or: ptr = (char **) calloc (MAXELEMS, sizeof(char*)); When is it a good idea to use calloc over malloc or vice versa? --------------Solutions------------- callo

  • calloc and copying data into memory area using c 2010-02-03

    I'm trying to allocate a block of memory and then copy data into that space. I made this simple program and it doesn't do what I expect it to do. Could someone please point out my faulty reasoning. Thanks. #include <stdio.h> #include <stdlib

  • Struggling to use calloc and realloc to initialize arrays in C 2010-02-06

    I'm struggling to use calloc and realloc for my array initializations. I'm trying to write a program which calculates a final sum from the command line arguments using fork() with a companion program. If I receive a odd set of integers from the comma

  • C tutorial question relating to calloc vs malloc 2010-02-06

    I am following this tutorial (http://theocacao.com/document.page/234). I am confused about this paragraph, mainly the lines relating to calloc: We can also use a variation of the malloc function, called calloc. The calloc function takes two arguments

  • Calloc inside function 2010-02-09

    Looking at this question that has just been asked: http://stackoverflow.com/questions/2231317/inconveniences-of-pointers-to-static-variables would doing something like this be considered bad practice, then? char* strpart(char* string, int start, int

  • calloc - Usefulness of zeroing out memory 2010-02-13

    What is the advantage of zeroing out memory (i.e. calloc() over malloc())? Won't you change the value to something else anyways? --------------Solutions------------- There are two camps: one says that initializing variables when they are declared hel

  • calloc v/s malloc and time efficiency 2010-04-09

    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 ar

  • 2d array, using calloc in C 2010-04-19

    I'm trying to create a 2D array of chars to storage lines of chars. For Example: lines[0]="Hello"; lines[1]="Your Back"; lines[2]="Bye"; Since lines has to be dynamically cause i don't know how many lines i need at first. Here is the code i have: int

  • C - Malloc or calloc-and how? 2010-04-30

    i have a text file where the first number defines the size of the arrays. I know that calloc or malloc can reserve memory, but how? this code: typedef struct alpha { int* size; char name; int tot; char line[60]; } ALPHA; fgets(line, 60, fp); tot = at

  • calling calloc - memory leak valgrind 2010-05-27

    The following code is an example from the NCURSES menu library. I'm not sure what could be wrong with the code, but valgrind reports some problems. Any ideas... ==4803== 1,049 (72 direct, 977 indirect) bytes in 1 blocks are definitely lost in loss re

  • C - calloc() v. malloc() 2010-08-10

    Possible Duplicate: c difference between malloc and calloc Please explain the significance of this statement, Another difference between the malloc() and calloc() functions is that the memory allocated by malloc( ) function contains garbage values, w

  • Strange char**/calloc behavior 2010-10-01

    When I debug the following code, strncpy works fine but as soon as the loop exits, I see that parent_var_names is pointing NULL/0xfdfdfddf. I am puzzled! parent_var_names = (const char**)calloc(net->nodes[x]->num_parents, sizeof(const char*));

  • Two arguments to calloc 2010-11-03

    Why does calloc take two arguments instead of one like malloc? Specifically, since there is no difference between (or is there?) between the following expressions: calloc (a, b); calloc (b, a); calloc (a * b, 1); calloc (1, a * b); why not just accep

Copyright (C) dskims.com, All Rights Reserved.

processed in 0.104 (s). 11 q(s)