1

I know that in C it is good practice to check for NULL pointer every time malloc() or calloc() is called. Do I have to do the same for array initialization? For example:

int sigcheck[5];
if (sigcheck == NULL) {return;}

Is line 2 necessary? If I'm not wrong, array initialization works like calling calloc() under the hood, does this under-the-hood functioning take the possibility of NULL into account or is it necessary/good practice for us to do it ourselves.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
ZarakshR
  • 804
  • 5
  • 14
  • 4
    Arrays are not pointers. An array owns the memory on its own. It does not need any `calloc` call or similar to get memory assigned. It can never be `NULL`. – Gerhardh May 24 '21 at 11:17
  • 1
    Only problem with arrays is with *VLA* (Variable Length Arrays). `int n; if (scanf("%d", &n) != 1) exit(EXIT_FAILURE); int vla[n];` may (silently) fail at runtime if `n` is large enough to make it fail. If this happens there is no check either :-( – pmg May 24 '21 at 14:25

3 Answers3

7

it is good practice to check for NULL pointer every time malloc() or calloc() is called

Yes, because those are functions documented to return NULL upon failure. That's the sole reason why.

do I have to do the same for array initialization

No.

Is line 2 necessary?

No, it doesn't make any sense. The array can't have address null, it always holds a memory position somewhere - where it ends up depends on something that C calls storage duration. In this case it either has static storage duration or automatic storage duration, depending on if it was allocated outside a function or inside a function.

If I'm not wrong, array initialization works like calling calloc() under the hood

You are wrong. calloc is a special case used for explicit memory allocation by the programmer, so called allocated storage duration. malloc family of functions is never called implicitly or silently. (Unless you call a function which claims to call malloc in turn, such as strdup.)

You might find this question interesting: A program uses different regions of memory for static objects, automatic objects, and dynamically allocated objects

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 2
    Overall, in case you are coming from Java or similar language where most things are silently stored on the heap... forget all about that. C is a completely different language. – Lundin May 24 '21 at 13:09
3

Memory for arrays is allocated like memory for any other variable type - there's no separate calloc or similar call under the hood. After the line

int sigcheck[5];

what you wind up with in memory is

          +---+
sigcheck: |   | sigcheck[0]
          +---+ 
          |   | sigcheck[1]
          +---+ 
           ...
          +---+
          |   | sigcheck[4]
          +---+

So there's no need to perform a NULL check against sigcheck in this case.

Where people get confused is that under most conditions the expression sigcheck will be converted, or "decay", from type "5-element array of int" to type "pointer to int", and the value of the expression will be the address of the first element of the array. This concept often gets garbled to where people think sigcheck is a pointer object separate from the array itself, but it isn't.

When you allocate memory dynamically through malloc or calloc, such as

int *sigcheck = calloc( 5, sizeof *sigcheck );

then (assuming the request succeeds) what you wind up with in memory is

          +---+
sigcheck: |   | ---+
          +---+    |
            +------+
            |  
            V
          +---+
          |   | sigcheck[0]
          +---+
          |   | sigcheck[1]
          +---+ 
           ...
          +---+
          |   | sigcheck[4]
          +---+

In this case the sigcheck is a separate object from the array elements. And because malloc, calloc, and realloc will return NULL if the memory request cannot be satisfied, then you do need to make a NULL check on sigcheck:

int *sigcheck = calloc( 5, sizeof *sigcheck );
if ( sigcheck )
{
  // do stuff
}
else
{
  // memory allocation failed, handle as appropriate
}
John Bode
  • 119,563
  • 19
  • 122
  • 198
1

From the documentation of malloc:

If the function failed to allocate the requested block of memory, a null pointer is returned.

So you should check whether malloc returns NULL precisely because it might fail to allocate you the requested chunk (although this is usually unlikely).

Static allocation does not call calloc under the hood, since that would allocate your array on the heap and not on the stack. The space needed for static allocations is determined at compile time, and if sufficient amount of memory cannot be allocated your program will fail to load. Take a look at this question.

K D
  • 194
  • 1
  • 13
  • Interesting. So array[8] cannot fail since the size is known at compile time. What happens if I use a dynamically allocated array like array[myVariable], cant that fail to initialize? – ZarakshR May 24 '21 at 11:32
  • That's another issue. Variable-length arrays are permitted in C99 in _local_ (and not global) scope only, and in that case, it's again the compiler that determines and allocates the size. – K D May 24 '21 at 11:37
  • You can't initialize variable-length arrays, you can only assign to them in run-time. – Lundin May 24 '21 at 13:08
  • if your program fails to allocate (rather than initialize) a VLA, the program should stop unilaterally — in my experience, it crashes. It means you've got a stack overflow (or over-allocation); you've tried to allocate too much space on the stack (which is normally limited to 8 MiB on Unix-like systems and 1 MiB on Windows). – Jonathan Leffler May 24 '21 at 14:20