Understanding Output for Malloc and Calloc Pointers?

  • Thread starter Thread starter transgalactic
  • Start date Start date
  • Tags Tags
    Code
AI Thread Summary
The discussion revolves around the use of `malloc` and `calloc` in C programming, focusing on memory allocation and initialization. It highlights that `calloc` initializes allocated memory to zero, while `malloc` does not guarantee initialization, potentially leading to garbage values. The output from the program shows that the arrays allocated with `calloc` contain zeros, while those allocated with `malloc` display unexpected values, indicating uninitialized memory. The conversation clarifies that both `calloc1[i]` and `*(calloc1 + i)` yield the same result, returning the value at the i-th index of the array. The confusion arises from a misunderstanding of memory initialization and the behavior of different compilers, particularly between Unix and Windows environments. The discussion emphasizes the importance of understanding memory management in C to avoid issues when porting code across platforms.
transgalactic
Messages
1,386
Reaction score
0
Code:
#include <stdio.h>
#include <stdlib.h> 
/* required for the malloc, calloc and free functions */

int main() {
  float *calloc1, *calloc2, *malloc1, *malloc2;
  int i;

  calloc1 = calloc(3, sizeof(float)); /* might need to cast */ 
  calloc2 = calloc(3, sizeof(float));
  malloc1 = malloc(3 * sizeof(float));
  malloc2 = malloc(3 * sizeof(float));

if(calloc1!=NULL && calloc2!=NULL && malloc1!=NULL && malloc2!=NULL) {

    for(i=0 ; i<3 ; i++) {
      printf("calloc1[%d] holds %05.5f, ", i, calloc1[i]);
      printf("malloc1[%d] holds %05.5f\n", i, malloc1[i]);
      printf("calloc2[%d] holds %05.5f, ", i, *(calloc2+i));
      printf("malloc2[%d] holds %05.5f\n", i, *(malloc2+i));
    }

    free(calloc1);
    free(calloc2);
    free(malloc1);
    free(malloc2);

    return 0;
  }
  else {
    printf("Not enough memory\n");
    return 1;
  }
}

Output:
calloc1[0] holds 0.00000, malloc1[0] holds -431602080.00000
calloc2[0] holds 0.00000, malloc2[0] holds -431602080.00000
calloc1[1] holds 0.00000, malloc1[1] holds -431602080.00000
calloc2[1] holds 0.00000, malloc2[1] holds -431602080.00000
calloc1[2] holds 0.00000, malloc1[2] holds -431602080.00000
calloc2[2] holds 0.00000, malloc2[2] holds -431602080.00000


at first they build 4 pointers
each one of them points to the start of a sector whose size is 3 float variables.

then the print some how
calloc1 should return only the address

*(calloc2+i) should return the data inside the address

but they get similar output

i can't understand these printf lines

??
 
Technology news on Phys.org
transgalactic said:
calloc1 should return only the address

*(calloc2+i) should return the data inside the address


Err, no. Both of those commands are equivalent, and return the data at the i-th element of the array calloc1.

If you want to return the address, use &calloc1 or calloc1+i.
 
the calloc needs to return an address to which every cell is empty
but when we print calloc1 (which is the content of cell "i")
we get the value -431602080.00000 instead of empty or some thing like that

why is that?
 
malloc and calloc are equivalent except that calloc also does a memset() on the allocated memory. In fact on most unix implementations they are identical - malloc will also return memory that is zeroed.
You are printing a float representation of some random memory contents (possibly all 1s?) only all bits zero is guaranteed to produce a float output of zero.
 
mgb_phys said:
malloc and calloc are equivalent except that calloc also does a memset() on the allocated memory. In fact on most unix implementations they are identical - malloc will also return memory that is zeroed.
You are printing a float representation of some random memory contents (possibly all 1s?) only all bits zero is guaranteed to produce a float output of zero.

That was also my understanding mgb. I wonder why it is that transg was getting calloc1 = -431602080.00000 in this case? (assuming some valid "i").
 
He isn't - all the calloc values are printing 0.0. That's part of IEEE float standard, all zero bits gives 0.0, the malloc are printing some garbage bcause the memory is initialised to something else.
Win32 inits malloc memory to 0xCE (or similair) so you know where it came from, some IBM machines used to use 0xDEADBEEF
 
mgb_phys said:
malloc and calloc are equivalent except that calloc also does a memset() on the allocated memory. In fact on most unix implementations they are identical - malloc will also return memory that is zeroed.

Which causes all kinds of havoc when porting between Unix compilers and, say, MSVC, as Unix developers tend to get into the habit of using malloc for everything. But then, I suppose that's what purify is for...
 
transgalactic said:
then the print some how
calloc1 should return only the address

*(calloc2+i) should return the data inside the address


There is absolutely no difference between *(calloc1+i) and calloc1 -- or i[calloc1], for that matter. The square brackets in C are just syntactic sugar1, unfortunately. The compiler immediate translates foo[bar] to *(foo+bar).


1 Except when they aren't syntactic sugar, which is even more unfortunate. The square brackets mean something quite different for multidimensional arrays such as double matrix[3][3] and ragged arrays such as double **ragged. With these declarations, matrix[2][2] is exactly the same as *(matrix+2+2*3) while ragged[2][2] is exactly identical to *(*(ragged+2)+2) .
 
mgb_phys said:
He isn't - all the calloc values are printing 0.0.

Ok but he did specifically say that this was not working for him though I agree that it should be printing zeros. Anyway I guess we can put this down to misinformation from a noob user in transgalactic?
 
Back
Top