Skip to content
FollowtheDamnCode

Reference: stdlib.h

Memory, conversions, random numbers, qsort, and exit.

6 minute read

Big idea

<stdlib.h> is the general utilities header: heap memory, converting text to numbers, random numbers, sorting and searching, and ending the program.

Memory

malloc

void *malloc(size_t bytes);

Reserves bytes bytes on the heap. Contents are garbage. Returns NULL if it can't. See malloc and calloc.

  • Gotcha: it takes bytes, not items — malloc(n * sizeof *p). Check for NULL.
  • Example: int *a = malloc(n * sizeof *a);

calloc

void *calloc(size_t count, size_t size);

Reserves count × size bytes, all set to zero.

  • Example: int *tally = calloc(26, sizeof *tally);

realloc

void *realloc(void *p, size_t bytes);

Resizes a heap block, keeping its contents; may move it. realloc(NULL, n) is malloc(n). See free and realloc.

  • Gotcha: on failure it returns NULL and leaves the old block alone — assign to a temporary first, or you leak it.
  • Example: int *t = realloc(a, cap * sizeof *t); if (t) a = t;

free

void free(void *p);

Gives a heap block back. free(NULL) does nothing.

  • Gotcha: free exactly once, never use the memory afterwards, never free something that didn't come from malloc/calloc/realloc.
  • Example: free(a); a = NULL;

Text to numbers

strtol / strtoul / strtoll

long strtol(const char *s, char **end, int base);

Converts text to a long in the given base (10 for decimal, 16 for hex, 0 to auto-detect 0x). Sets *end to the first character it didn't use; sets errno to ERANGE if the number is too big. See Error Handling.

  • Gotcha: it's the only family here that can report errors — check end != s and *end == '\0'.
  • Example: char *end; long v = strtol("42", &end, 10);

strtod

double strtod(const char *s, char **end);

The same, for decimals.

  • Example: double d = strtod("2.5e3", NULL); → 2500

atoi / atol / atof

int atoi(const char *s);
double atof(const char *s);

Quick conversions with no error reporting: junk gives 0.

  • Gotcha: atoi("abc") and atoi("0") both return 0. Fine for tests, not for user input.
  • Example: int n = atoi(argv[1]);

Integer maths

abs / labs / llabs

int abs(int x);
long labs(long x);

Absolute value of an integer. (fabs for doubles is in <math.h>.)

  • Gotcha: abs(INT_MIN) overflows — there's no positive version of the smallest int.

div

div_t div(int a, int b);

Quotient and remainder at once: .quot and .rem.

  • Example: div_t r = div(17, 5); → r.quot 3, r.rem 2

Random numbers

rand / srand

int rand(void);
void srand(unsigned seed);

rand returns 0 to RAND_MAX (at least 32767). srand seeds the sequence. See Math, Random Numbers, and Time.

  • Gotcha: seed once — srand(time(NULL)) at the start of main. Not suitable for anything secret.
  • Example: int die = rand() % 6 + 1;

Sorting and searching

qsort

void qsort(void *base, size_t count, size_t size,
           int (*cmp)(const void *, const void *));

Sorts any array using your comparator. See Function Pointers and Callbacks.

  • Gotcha: the comparator gets pointers to elements. Return negative / 0 / positive; avoid a - b (overflow).
  • Example: qsort(a, n, sizeof a[0], cmp_int);

bsearch

void *bsearch(const void *key, const void *base, size_t count, size_t size,
              int (*cmp)(const void *, const void *));

Binary search in a sorted array, using the same kind of comparator. Returns a pointer to a match, or NULL.

  • Example: int *hit = bsearch(&target, a, n, sizeof a[0], cmp_int);

Ending the program and the environment

exit

void exit(int status);

Ends the program from anywhere, flushing open files. EXIT_SUCCESS (0) and EXIT_FAILURE are defined here.

  • Example: if (cfg == NULL) exit(EXIT_FAILURE);

getenv

char *getenv(const char *name);

Reads an environment variable; NULL if it isn't set.

  • Example: const char *home = getenv("HOME");

system

int system(const char *command);

Runs a shell command. Avoid it with any text that came from a user.

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

int cmp_int(const void *pa, const void *pb) {
    int a = *(const int *) pa, b = *(const int *) pb;
    return (a > b) - (a < b);
}

int main(void) {
    const char *words[] = {"40", "-7", "15", "8"};
    int n = 4;
    int *a = malloc(n * sizeof *a);
    if (a == NULL) return EXIT_FAILURE;
    for (int i = 0; i < n; i++) a[i] = (int) strtol(words[i], NULL, 10);

    qsort(a, n, sizeof a[0], cmp_int);
    for (int i = 0; i < n; i++) printf("%d ", a[i]);
    printf("\n");

    int key = 15;
    int *hit = bsearch(&key, a, n, sizeof a[0], cmp_int);
    printf("15 is at index %d\n", hit ? (int) (hit - a) : -1);

    div_t r = div(17, 5);
    printf("17 = 5*%d + %d, abs(-9) = %d\n", r.quot, r.rem, abs(-9));
    free(a);
    return EXIT_SUCCESS;
}
output
-7 8 15 40 
15 is at index 2
17 = 5*3 + 2, abs(-9) = 9

Run and edit it in the app.

Which function lets you detect that "12abc" isn't a clean number?

Check yourself

What does realloc return if it fails?

What does bsearch need that qsort doesn't?