Almost every function in C standard library returns something on success, and something else on error. For example, malloc
will return a pointer to the memory block allocated by the function on success, and, if the function failed to allocate the requested block of memory, a null pointer. So you should always check the return value for easier debugging.
This is bad:
char* x = malloc(100000000000UL * sizeof *x);
/* more code */
scanf("%s", x); /* This might invoke undefined behaviour and if lucky causes a segmentation violation, unless your system has a lot of memory */
This is good:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char* x = malloc(100000000000UL * sizeof *x);
if (x == NULL) {
perror("malloc() failed");
exit(EXIT_FAILURE);
}
if (scanf("%s", x) != 1) {
fprintf(stderr, "could not read string\n");
free(x);
exit(EXIT_FAILURE);
}
/* Do stuff with x. */
/* Clean up. */
free(x);
return EXIT_SUCCESS;
}
This way you know right away the cause of error, otherwise you might spend hours looking for a bug in a completely wrong place.