Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I'm very confused about malloc() and calloc() on C

I've always programmed in Java, which is probably why I'm so confused about this:

In Java I declare a pointer:

int[] array 

and initialize it or assign it some memory:

int[] array = {0,1,0} int[] array = new int[3] 

Now, in C, it's all so confusing. At first I thought it was as easy as declaring it:

int array[] 

and initializing it or assigning it some memory:

int array[] = {0,1,0} int array[] = malloc(3*sizeof(int)) int array[] = calloc(3,sizeof(int)) 

Unless I'm wrong, all of the above is equivalent Java-C, right?

Then, today I met a code in which I found the following:

pthread_t tid[MAX_OPS]; 

and some lines below, without any kind of initialization...

pthread_create(&tid[0],NULL,mou_usuari,(void *) 0); 

Surprisingly (at least to me), the code works! At least in Java, that would return a nice "NullPointerException"!

So, in order:

  1. Am I correct with all of the Java-C "translations"?

  2. Why does that code work?

  3. Is there any difference between using malloc(n*sizeof(int)) and calloc(n,sizeof(int))?

Thanks in advance

like image 745
bluehallu Avatar asked Nov 21 '10 12:11

bluehallu


People also ask

Is it better to use malloc () or calloc ()?

Malloc() VS Calloc(): Explore the Difference between malloc() and calloc() malloc() and calloc() functions are used for dynamic memory allocation in the C programming language. The main difference between the malloc() and calloc() is that calloc() always requires two arguments and malloc() requires only one.

What is malloc () and calloc () in C?

Malloc() function is used to allocate a single block of memory space while the calloc() in C is used to allocate multiple blocks of memory space. Each block allocated by the calloc() function is of the same size.

What can I use instead of malloc in C?

An array in C or C++ is a collection of items stored at contiguous memory locations and elements can be accessed randomly using indices of an array. They are used for storing similar types of elements as the data type must be the same for all elements.

Why malloc is faster than calloc in C?

In malloc function, number of arguments is 1 while in calloc function, number of argument is 2. malloc() time efficiency is higher than calloc() whereas malloc() is not secure as compared to calloc() malloc does not initialize memory whereas calloc performs memory initialization.


1 Answers

You can't assign memory to an array. An array has a fixed size, for the whole of its lifespan. An array can never be null. An array is not a pointer.

malloc returns the address to a memory block that is reserved for the program. You can't "assign" that (being the memory block) to an array, but you can store the address of this memory block in a pointer: luckily, array subscription is defined through pointers - so you can "use pointers like arrays", e.g.

int *ptr = malloc(5 * sizeof *ptr); ptr[2] = 5; // access the third element "of ptr" free(ptr); // always free at the end 

When you declare an array without a size (i.e. array[]), it simply means the size of the array is determined from the initializer list. That is

int array[] = {1, 2, 3, 4, 5}; // is equal to int array[5] = {1, 2, 3, 4, 5}; 

Trying to declare an array without a size and without an initializer is an error.


The code pthread_t tid[MAX_OPS]; declares an array named tid of type pthread_t and of size MAX_OPS.

If the array has automatic storage (i.e. declaration is inside a function and not static, not global), then each of the arrays elements has indeterminate value (and it would cause undefined behavior trying to read such value). Luckily, all that the function call does is that it takes the address of the first element of the array as the first parameter, and probably initializes it (the element) inside the function.


The difference of calloc and malloc is that the memory block that calloc returns is initialized to zero. That is;

int *ptr = calloc(5, sizeof *ptr); // is somewhat equal to int *ptr = malloc(5 * sizeof *ptr); memset(ptr, 0, 5 * sizeof *ptr); 

The difference between

int *ptr = malloc(5 * sizeof *ptr); // and int array[5]; 

is that array has automatic storage, (is stored on stack), and is "released" after it goes out of scope. ptr, however, (is stored on heap), is dynamically allocated and must be freed by the programmer.

like image 121
eq- Avatar answered Sep 17 '22 13:09

eq-