1
int* ptr;
ptr=(int*)malloc(sizeof(int)); //(A)
ptr=(int*)malloc(5*sizeof(int)); //(B)

At line (A), a block of 4 byte is going to create dynamically. Now that's fine. But my question is at line B is it going to create a single 20(5*4) byte block? Or 5 separate blocks of size 4 byte? If it creates a separate block then will they be contiguous? Is ptr=(int*)malloc(5*sizeof(int)); and ptr=(int*)calloc(5,sizeof(int)); equivalent?

  • Create a function like this: `void foo(int x) { printf("%d\n", x); }`, now call it: `foo(5*sizeof(int));`. Does it print `20` or does it print `5*sizeof(int)`? Why? Is that sufficient information for you to be able to answer this question yourself? How would malloc know the difference between `8*sizeof(int8_t)`, `4*sizeof(int16_t)`, `2*sizeof(int32_t)` and `1*sizeof(int64_t)`? – Art Aug 17 '17 at 10:56
  • 2
    Don't cast the return of malloc. – David Hoelzer Aug 17 '17 at 10:57

6 Answers6

2

They are practically equivalent. malloc will allocate contiguous block. Difference is that calloc does zero initialization of the memory, while malloc doesn't.

Of course, we are talking about virtual memory. The block will be contiguous for your program. It can be not in physical memory. But it is not important in most cases, until you do not try to do kernel modules or drivers, which work in ring 0. But it is the different story.

  • I added the comment about the difference of virtual memory and physical memory. Virtual memory must be contiguous, because `malloc` doesn't unserstand, do you pass `(sizeof(int) * 4)` or `sizeof(MyMegaStructure)` – Melnikov Sergei Aug 17 '17 at 10:51
2

But my question is at line B is it going to create a single 20(5*4) byte block?

ptr = malloc(5*sizeof(int)) will allocate 5*sizeof(int) bytes of space. Yes allocated space will be contiguous, if contiguous space is not available then allocation will fail.

Is ptr=(int*)malloc(5*sizeof(int)); and ptr=(int*)calloc(5,sizeof(int)); equivalent?

They are equivalent except that calloc sets the allocated memory to 0.


NOTE: In C, you should not cast the return value of malloc, calloc and realloc.

haccks
  • 104,019
  • 25
  • 176
  • 264
  • 1
    I didnt DV, but i guess its caused by _"They may or may not be contiguous"_. It depends if we are talking about virtual/physical memory. – kocica Aug 17 '17 at 10:46
  • @FilipKočica; That could be the reason. Now I made it simple. – haccks Aug 17 '17 at 10:49
2

malloc() tries to allocate the size of memory that you asked for. The function doesn't know how the parameter is transferred, but rather it's value alone.

For example, if sizeof(int) is 4, then:

int* ptr = malloc(sizeof(int) * 5);

and

int* ptr = malloc(20);

are essentially the same. In both the function will get a value of 20 as a parameter. The same will happen if you call malloc like this:

size_t a = 20;
int* ptr = malloc(a);

Therefore, if it succeeds (i.e. doesn't return NULL), it will allocate a contiguous block of memory, with at least the size that you asked for.

All that is true regarding to virtual memory. Meaning, you'll access the memory with a continuous index. Physical memory depends on the way the OS manages you're memory.

If, for example, your OS holds memory page frames (blocks of physical memory) in size of 4kb only, and you ask in malloc for more, although your virtual memory will be contiguous, physical memory might not.

All of that has to do with a wider subject that is called memory management. You can read about the way that linux chose to deal with it here.

Noam Ohana
  • 186
  • 14
1

Malloc takes requested size of block to be allocated, expressed in bytes. It does not (and cannot, really) determine how you got a given number i.e. if the size is 5*sizeof(int) as in your example or it's 20 or 30-10. It's going to allocate a single block of 20 bytes in either case (assuming size of int is 4 bytes).

J_S
  • 2,985
  • 3
  • 15
  • 38
0

First of all, it's bad to cast the return value of malloc(). This function takes as input the number of bytes that you want to allocate. It doesn't matter whether you pass (5*sizeof(int)) or 20 (assuming an int is 4 bytes on your machine). A chunk with the given number of bytes will be allocated. When I say chunk, I mean that you can access each byte like this:

char *ptr = malloc(5*sizeof(int));
ptr++;  // now ptr points to the second byte of the chunk.

Or, you could do something like this:

int *ptr = malloc(5*sizeof(int));
ptr++;  // now ptr points to the second element (that's sizeof (int) bytes away) from the start of the chunk.

Is ptr=(int*)malloc(5*sizeof(int)); and ptr=(int*)calloc(5,sizeof(int)); equivalent?

When using malloc, you should not assume anything about the contents of the chunk of memory. When you use calloc all the bytes in the chunk is guaranteed to be set to 0. malloc might be faster than calloc on some implementations. Other than that there is no difference.

babon
  • 3,615
  • 2
  • 20
  • 20
0
  1. Yes it does. malloc will allocate contiguous block, or malloc will fail if there isn't a large enough contiguous block available. (A failure with malloc will return a NULL pointer.)

  2. Malloc and Calloc both allocate the memory but calloc initialise to zero while malloc does not.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
suraj
  • 403
  • 4
  • 15