0

I'm reading a C code that do

char * buf = malloc(sizeof (char *) * 16)

instead of

char buf[sizeof (char *) * 16]

what's the difference? well, I think the first expression unnecessary, if realloc() is not called, or am I wrong thinking?

halfer
  • 19,824
  • 17
  • 99
  • 186
Jack
  • 16,276
  • 55
  • 159
  • 284
  • 3
    It's the difference between an automatic array and a dynamic array. One resides in automatic storage and you do not have to deallocate it, and one resides in dynamic storage and you do have to deallocate it. Prefer the first. – Seth Carnegie Mar 01 '12 at 04:53
  • 1
    The first line dynamically allocates **an array of bytes (chars) as long as the size of a pointer (perhaps 4 bytes) multiplied with 16 = 64 bytes**. This doesn't make any sense. The second line statically allocates **an array of bytes (chars) as long as the size of a pointer multiplied with 16 = 64 bytes.** This doesn't make any sense either. – Lundin Mar 01 '12 at 07:43
  • donwvotes - can explain please? – Jack Mar 01 '12 at 23:57

4 Answers4

5

char buf[sizeof(char*)*16] is an array allocated automatically, which is generally the stack. It is valid as long as buf is in scope, and there is sufficient stack space.

malloc allocates memory from some heap. It is valid until this memory is free()ed. Generally, there is much more heap available.

Yann Ramin
  • 32,895
  • 3
  • 59
  • 82
1

Yann's note is correct.

This appears to be an array of pointers. Since it is allocating memory for 16 times the size of a char pointer. Pointer size can vary on different systems. Pointers on some are 32-bit (4 bytes) where others are 64-bit (8 bytes).

char buf[sizeof(char *) * 16] is not an array of pointers, it's an array of chars that has elements equal to the size of a char pointer times 16.

Brett W
  • 351
  • 1
  • 4
1

Dynamic Array

The first one, is a dynamic array. The expression char * buf = malloc(sizeof (char *) * 16) stores the elements in memory ( the malloc is basically used for memory allocation ). The advantages of using it are, you can reallocate it, i.e resize it during runtime. However, you may have to allocate new memory every time you add a new element. Here's an example:

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
int main() {
  int* array;
  int n, i;
  printf("Enter the number of elements: ");
  scanf("%d", &n);
  array = malloc(n*sizeof(int));
  for (i=0; i<n; i++) {
  printf("Enter number %d: ", i);
  scanf("%d", &array[i]);
  }
  printf("\nThe Dynamic Array is: \n");
  for (i=0; i<n; i++) {
  printf("The value of %d is %d\n", i, array[i]);
  }
  printf("Size= %d\n", i);
  getch();
  return 0;
}

The output:

Output

Automatic (Static?) Array

The second expression char buf[sizeof (char *) * 16] just declares a boring automatic array. It's size is static. No dynamic resizing, reallocation etc.

note: apologies for the type cast before malloc. typecasting the return value of malloc will result in the compiler not giving an error if you do something wrong. This may be followed by undefined runtime errors and debugging hell. Always avoid typecasting the result of malloc. Thanks @Lundin.

Community
  • 1
  • 1
ApprenticeHacker
  • 21,351
  • 27
  • 103
  • 153
  • 2
    -1 for teaching to typecast the result of malloc. See the [C FAQ](http://c-faq.com/malloc/mallocnocast.html) and [this post](http://stackoverflow.com/questions/1565496/specifically-whats-dangerous-about-casting-the-result-of-malloc). Please correct this and I will remove the downvote. – Lundin Mar 01 '12 at 07:39
  • @Lundin sorry about that. Thanks for the post, currently removing all type casts before `malloc` from my own past C code-base. :) – ApprenticeHacker Mar 01 '12 at 07:49
  • There are compilers that complain if you don't typecast, such as the one at [mbed](http://www.mbed.org), where you can't adjust the settings :/ – Yusuf X Apr 27 '12 at 17:51
0

The main difference is that if this is code is in a function, you can still use the pointer declared in the former after you return.

Yusuf X
  • 14,513
  • 5
  • 35
  • 47