gcc 4.5.1 c89
I have written this source code for my better understanding of malloc and calloc.
I understand, but just have a few questions
malloc(n) allocates n bytes plus padding and overhead.
calloc(m, n) allocates m*n bytes plus padding and overhead, and then zero's the memory.
That's it.
All three loops in your program use only one struct Devices
object at a time. The later ones allocate extra memory as though they are going to use multiple objects, but then keep overwriting the beginning of that memory. If you tried to use the object with ID 1 after setting up the object with ID 2, you would find there is no longer any object with ID 1.
Instead, you could do something like this to treat the allocated memory as an array of structs:
dev_malloc = malloc(num_devices * sizeof *dev_malloc);
for (i=0; i<num_devices; i++) {
/* Assign values */
dev_malloc[i].id = i + 1;
sprintf(dev_malloc[i].name, "dev_malloc%zu", dev_malloc[i].id);
/* Print values */
printf("ID ----- [ %zu ]\n", dev_malloc[i].id);
printf("Name --- [ %s ]\n", dev_malloc[i].name);
}
free(dev_malloc);
edited for clarity
The first one malloc(number * sizeof(*devices))
would allocate enough memory to store number
of Device
s. As others have mentioned, you can treat this block like an array of Device
. The pointer you get back will point to the beginning of the block.
int number = 5;
Device *ptr = malloc(number * sizeof(*ptr));
/* stuff */
free(ptr);
The second one that uses calloc
does the same thing, while also initializing the memory to 0. Again, you can use treat the block like an array of Device
.
int number = 5;
Device *ptr = calloc(number, sizeof(*ptr));
/* stuff */
free(ptr);
The third one, looping 5 times, would result in 5 different pointers to 5 different blocks large enough to store one Device
each. This also means each of the 5 pointers has to be free
'ed individually.
Device *ptrs[5];
for(int i = 0; i < 5; ++i)
{
ptrs[i] = malloc(sizeof(*ptrs[i]));
}
/* stuff */
for(int i = 0; i < 5; ++i)
{
free(ptrs[i]);
}
Look at an implementation of calloc to see the differences. It's probably something like this:
// SIZE_MAX is defined in stdint.h from C99
void *calloc( size_t N, size_t S)
{
void *ret;
size_t NBYTES;
// check for overflow of size_t type
if (N > SIZE_MAX / S) return NULL;
NBYTES = N * S;
ret = malloc( NBYTES);
if (ret != NULL)
{
memset( ret, 0, NBYTES);
}
return ret;
}
calloc(a,b)
and malloc(a*b)
are equivalent except for the possibility of arithmetic overflow or type issues, and the fact that calloc
ensures the memory is zero-byte-filled. Either allocated memory that can be used for an array of a
elements each of size b
(or vice versa). On the other hand, calling malloc(b)
a
times will results in a
individual objects of size b
which can be freed independently and which are not in an array (though you could store their addresses in an array of pointers).
Hope this helps.
As you point out, calloc
zeroes out the memory is allocates, while malloc
doesn't.
Your examples 1 & 2 each allocate a single contiguous block of five structs (and returns a pointer to that block), whereas example 3 allocates five separate blocks of one struct each (and gives you five pointers unrelated to one another.)