Two arguments to calloc
Why does calloc take two arguments instead of one like malloc?
Specifically, since there is no difference between (or is there?) between the following expressi开发者_开发技巧ons:
calloc (a, b);
calloc (b, a);
calloc (a * b, 1);
calloc (1, a * b);
why not just accept the total number of bytes to allocate? What is the rationale behind this interface? And why does this not apply to malloc?
I heard two [mutually exclusive] explanations for why it has two arguments:
calloctakes the responsibility for checking for overflow on multiplication. If the total size of the requested block is too large (like overflowssize_t),callocreturns null pointer to indicate failure. Withmallocyou have to watch for overflow yourself, which many people simply forget to do. (Although the history of standard library knows examples ofcallocimplementations that ignored overflow, and thus worked incorrectly).callocactually allows one to allocate bigger blocks of memory than the range of typesize_t, i.e.callocmight be capable of performing the proper non-overflowing large multiplication of its arguments and allocate the block of the resultant size. For this reason, sincecallocuses two arguments of typesize_t, it can allocate bigger blocks thanmallocwill ever be able to (sincemalloctakes only one argument of typesize_t).
I always believed that the first explanation is the right one. However, after reading some posts here on SO I have my doubts.
I believe that malloc is guaranteed to return an area of memory which is aligned according to the coarsest requirement that would be compatible with the size indicated by the second argument. For example, if the system requires alignment of 2 and 4-byte integers, and the second argument is 10, the returned pointer must be aligned on a two-byte boundary; if the second argument were 12, the pointer would be aligned on a four-byte boundary. I suspect that in practice many systems will align all returned pointers to the largest possibly-required boundary, regardless of size, but I don't think it's required except for calloc.
The only notable difference is that calloc is required to initialize the allocated space to zeroes while there is no such guarantee with malloc. Otherwise, I guess there are two different functions just for historical reasons.
Everything is just bytes is a relatively new (ie c/Unix era) invention - on a lot of other architecture things were fixed sized records.
calloc(x,y) is a equivalent to malloc(x*y)
But calloc doing additional (setting values to 0 with) memset(block, 0, x*y)
This function is only for pretty way pass the size of element and number of elements, when in malloc you must multiply this values to get needed number of bytes, this function check integer overflow too in multiplication.
For example if you want allocate memory for 12 integers and you want do something with this integers and you must have setted her values to 0, use calloc(12, sizeof(int))
But if you want allocate some memory block (256 bytes) to copy in future to it some string then memset is a not usable for you, then better use is malloc(sizeof(char) * 256) or for example malloc(sizeof(wchar_t) * 256)
void *
calloc (size_t nmemb, size_t lsize)
{
void *ptr;
struct __meminfo *info;
size_t size = lsize * nmemb;
/* if size overflow occurs, then set errno to ENOMEM and return NULL */
if (nmemb && lsize != (size / nmemb))
{
set_errno (ENOMEM);
return NULL;
}
/* allocate memory */
ptr = malloc (size);
/* get pointer to info part of chunk */
info = __mem2info (ptr);
/* fill memory with zeros and set __MEM_CALLOC flag */
memset (ptr, 0, info->size);
info->flags |= __MEM_CALLOC;
return ptr; /* happy end */
}
加载中,请稍侯......
精彩评论