1

I was writing some code and I used the function calloc.

I understand that, when the first and the second arguments passed to this function are both zero, the function is going to alloc the necessary space for 0 elements, each of them with size 0, but here is the strange thing.

This program works fine even if n > 0. Why is that happening? I think it should display an error because I'm trying to write in a position of the array that doesn't exist. Thanks!

#include <stdio.h>
#include <stdlib.h>

int main(){
  int n;
  scanf("%d", &n);
  int *test = calloc(0, 0);
  for(int i = 0; i < n; i++){
    test[i] = 100;
    printf("%d ", test[i]);
  }
  return 0;
}
Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
marcosk
  • 13
  • 4
  • 6
    Undefined behavior means anything can happen. – Kevin Jan 04 '17 at 22:25
  • 1
    no syntax errors = no compile errors in `c`. What you have compiles fine, but you are writing beyond your memory region (when `n > 0`) which is undefined behavior. – yano Jan 04 '17 at 22:25
  • 1
    You don't get errors for things like this in c. It will just try and write it to the address specified. You as the programmer have to be careful to make sure it doesn't happen. – Paul Rooney Jan 04 '17 at 22:28

1 Answers1

0

In C, a lot of wrong and "wrong" things don't display error messages from the compiler. In fact, you may not even see error messagens when you run the program -- but another person running your program in a different computer may see the error.

One important concept in C is called undefined behavior. To put it in simple terms, it means that the behavior of your program is unpredictable, but you can read more about this subject in this question: Undefined, unspecified and implementation-defined behavior.

Your program is undefined for a two reasons:

  1. When either size or nmemb is zero, calloc() may return NULL. Your program is not checking the output of calloc(), so there's a good chance that when you do test[i] you are attempting to derreference a NULL pointer -- you should always check the result of calloc() and malloc().
  2. When you call malloc() or calloc(), you are essentialy allocating dynamic memory for an array. You can use your pointer to access the elements of the array. But you can't access anything past the array. That is, if you allocate n elements you should not try to access the n+1-th element -- nether for reading.

Both items above make your program invoke undefined behavior. There might also be something undefined about accessing an empty object other than item #2 listed above, but I'm unsure.

You should always be careful about undefined behavior because, when your program invokes UB, it is essentialy unpredictable. You could see a compilation error, the program could give an error messagen, it could run successfuly without any problems or it could wipe out every single file in your hard disk.

Community
  • 1
  • 1
giusti
  • 3,156
  • 3
  • 29
  • 44