5 ms·
Calloc or Malloc? Any thoughts?
To the best of my understanding, it is largely equivalent to say:
int * i;
i = (int * ) malloc(10 * sizeof(int));
as it is to say:
int * i;
i = (int*) calloc(10,sizeof(int));
The one allocates a memory block of size 10 times sizeof(int), the other allocates ten memory blocks each of size sizeof(int) and has them all initialized to 0. So effectively the only difference in this case is calloc initializes the blocks to 0 whereas malloc does not. And calloc is more computationally expensive. But in the end a similar result obtains.
Normally I use malloc, but out of curiousity I read up about calloc and this seems to be the answer, that they are basically the same except calloc initializes n number of blocks to size size_t instead of 1 block of some given size size_t, calloc initializes the values to 0 where malloc does not, and calloc takes more time for the cpu to do than malloc does. So with some minor differences the above two statements should do the same thing - i.e. I can use the int arrays allocated thusly the same. I think. :-)
Anybody have any thoughts? Which is better to use normally?
(by the way http://www.cs.cf.ac.uk/Dave/C/node11.html is where I was reading up on these functions)
- akv 18y agoneither.. try using a language does dynamic memory allocation and garbage collection... it would save you a lot of headache...
- qwph 18y ago...unless you're writing code for an embedded system which has (say) 16K of RAM and a 1MHz processor, in which case that will cause you more problems than it solves.
- yan 18y agoBut what about when you are adding features or fixing bugs in the gigantic base of code written in C? Or what if you consider C your lingua-franca and find it no less difficult to write a throw away app in C over other languages. Or if you have to interface very closely to your operating system without writing hairy wrapperes. Or, or, or ...
- tptacek 18y agocalloc by default, then profile your code, and if memset or calloc hits the top of the profile, start pruning them out. You get a much bigger performance win out of swapping in a pool allocator, or, even better, arenas.
- yan 18y agoI always use calloc when allocating many blocks at once, as you said. Yes, you get a free bzero() with it, but that's not why I use it. When I'm trying to allocate memory for many blocks of something, I'd use calloc just because it makes my intentions clearer in the code when someone else is reading it. If I'm allocating memory just for one area or block, I'd use malloc+bzero or possibly calloc with a clear block count of one. The efficiency in the end is pretty equivalent but it makes your code easier to digest to other people.
- noodle 18y agoi only use calloc when i have any chance of addressing an area that could ever potentially be empty. i more typically malloc if i'm making space and immediately fill it up completely with whatever goes in it so that any of the previous garbage is gone
- orib 18y agoFirst: Lose the cast. It's not needed in C, clutters the code, and can hide real problems (like implicit declarations of the functions -- this can cause crashes on 64-bit architectures). A void* exists solely so it can be assigned to any type* without casts. It's useless for any other purpose. Yes, they are effectively the same. I'd suspect that on most systems (glibc, certainly) calloc more or less does: mem = malloc(nelem * size); memset(mem, 0, nelem * size); return mem;
- sysop073 18y agoHe didn't actually say he was using C, and I always include the cast. It's more portable, and doesn't really clutter the code since everyone is used to seeing that exact expression
- earle 18y agoCalloc clears the memory to all bits zero. All bits zero doesn't necessarily mean zero values. Not many people will make this distinction and happily write broken code thinking that calloc always clears the values to zero accordingly. calloc's zero fill is all-bits-zero, and is therefore guaranteed to yield the value 0 for all integral types, and '\0' for character types -- but does not guarantee useful null pointer values or floating-point zero values. Some C implementations represent null pointers by special, nonzero bit patterns when it can be arranged so that inadvertently using those values triggers automatic hardware traps.
- yan 18y agoI'm just curious, but can you point me to an implementation of C that doesn't treat (void*)0 as NULL?
- qwph 18y ago( void* )0 is NULL, in that NULL is (most usually) #defined to be ( void* )0. But the literal 0 in a pointer context doesn't guarentee that the null pointer is actually all bits zero. To put it another way, if you have a literal zero in a pointer context, the compiler will replace it with the machine's representation of a null pointer, which may or may not be a machine word with all bits zero. I think that's right...
- dmm 18y agoFrom the openbsd man page malloc(3): When using malloc() be careful to avoid the following idiom: if ((p = malloc(num * size)) == NULL) err(1, "malloc"); The multiplication may lead to an integer overflow. To avoid this, calloc() is recommended.
- sysop073 18y agoMaybe it's different on OpenBSD, but I think the spec says they're essentially equivalent; i.e. it's permissible to just call malloc with the product from within calloc
- DarkShikari 18y agoIf you want the benefit of the clearness of calloc without the time wasted on memset--just write a wrapper for malloc. Its not much effort, and it gets you the best of both worlds.