Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C - How to use own value (instead of 0) with calloc

In C when we use the calloc method; all the reserved memory will be initialized to 0.

Is there any way to initialize it with another value without iterating over all the values? For example:

int* example = calloc(100,sizeof(int));

This will create an array of 100 zero's, but I want this to be (for example) 100 ones.

like image 376
Domien Avatar asked Dec 25 '22 13:12

Domien


1 Answers

calloc as much as memset has no idea about the structure of the data stored in the allocated block. It is actually of little use to use memset with anything different from 0 on something other than an array of char type. Note that calloc is functionally malloc plus memset(..., 0), but might be significantly faster in some implementations.

According to the standard, calloc does not store 0, but sets all bits zero. This does not necessarily result in a float 0.0 or a null pointer constant, as they might have other binary representations. For integer types, however, 0 has all bits zero, so this works.

But only for the 0, because on most (if not all) modern platforms integer uses at least 2 bytes, so if you set byte-wise, you will touch different bytes of the same integer. Just try memset(..., 3), for 32 bit int you will read 0x03030303, for 64 bit 0x0303030303030303.

To set structured values of an allocated array, there is no way around using a loop:

// here we use int, but that can also be float or a struct
int *a = malloc(sizeof(*a) * 5);
if ( a != NULL ) {
    for ( size_t i = 0 ; i < 5 ; i++)
        a[i] = 1;    // for a struct use a compound literal or set per field

    ...
    free(a);
}

You should not worry about performance in the first place. The pattern above is very likely recognised by your compiler and replaced by highly optimised code which will be as fast (if not faster) as memset (but not calloc).

like image 131
too honest for this site Avatar answered Jan 08 '23 12:01

too honest for this site