Cstdlib.h Utilities

stdlib.h Utilities

stdlib.h is one of the busiest headers in the standard library — it is where dynamic memory allocation, number parsing, random numbers, generic sorting, and program termination all live. This page is a curated tour of the utilities you will reach for most often, beyond the malloc family covered on its own page.

Memory functions (recap)

malloc, calloc, realloc, and free are the dynamic memory functions declared in stdlib.h. They get a full page of their own elsewhere in this section — see the dedicated malloc/calloc/ free pages for allocation patterns and pitfalls.

Converting strings to numbers

Reading numeric input often starts life as text — from argv, a config file, or fgets. stdlib.h provides two families of conversion functions:

Function

Converts to

Error reporting

atoi, atof

int, double

None — returns 0 on failure, indistinguishable from a real zero.

strtol, strtoul

long, unsigned long

Robust — sets errno and reports how far parsing got via an endptr parameter.

strtod

double

Robust — same endptr mechanism as strtol.

atoi cannot tell you it failed
`atoi("abc")` and `atoi("0")` both return 0. There is no way to distinguish a genuine zero from a parse failure. For anything where invalid input is a real possibility (which is almost always, for user or file input), prefer `strtol`/`strtod`, which let you check an end pointer to see whether any digits were actually consumed.

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

int main(void) {
    const char *text = "123abc";
    char *endptr;

    long value = strtol(text, &endptr, 10);

    printf("parsed value: %ld\n", value);
    if (*endptr != '\0') {
        printf("stopped parsing at: \"%s\"\n", endptr);
    }

    return 0;
}
parsed value: 123
stopped parsing at: "abc"
Pseudo-random numbers

rand() returns a pseudo-random integer between 0 and RAND_MAX. srand(seed) seeds the generator — typically called once, near the start of main, with a value like time(NULL) so each run produces a different sequence.

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

int main(void) {
    srand((unsigned int)time(NULL));

    for (int i = 0; i < 5; i++) {
        int roll = (rand() % 6) + 1; // 1..6
        printf("roll %d: %d\n", i + 1, roll);
    }

    return 0;
}
rand() is not a security tool
`rand()` is fine for games, simulations, and shuffling — but it is not cryptographically secure, and on some older C library implementations its low-order bits have poor statistical quality. Never use `rand()` to generate passwords, tokens, or keys; use a platform cryptographic API for that instead.
Generic sorting with qsort

qsort sorts any array in place, given the array, the element count, the element size, and a comparator function pointer you supply. The comparator receives two const void * pointers and must return negative, zero, or positive depending on their relative order — the same convention used throughout the standard library (see strcmp).

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

int compare_ints(const void *a, const void *b) {
    int x = *(const int *)a;
    int y = *(const int *)b;
    return (x > y) - (x < y);
}

int main(void) {
    int nums[] = {5, 2, 9, 1, 7};
    size_t n = sizeof(nums) / sizeof(nums[0]);

    qsort(nums, n, sizeof(int), compare_ints);

    for (size_t i = 0; i < n; i++) {
        printf("%d ", nums[i]);
    }
    printf("\n");

    return 0;
}
1 2 5 7 9

The same function sorts arrays of structures too — the comparator just needs to cast to the right struct type and compare whichever field matters:

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

typedef struct {
    char name[32];
    int age;
} Person;

int compare_by_age(const void *a, const void *b) {
    const Person *p1 = a;
    const Person *p2 = b;
    return p1->age - p2->age;
}

int main(void) {
    Person people[] = {
        {"Alice", 34},
        {"Bob", 21},
        {"Carla", 45},
    };
    size_t n = sizeof(people) / sizeof(people[0]);

    qsort(people, n, sizeof(Person), compare_by_age);

    for (size_t i = 0; i < n; i++) {
        printf("%s (%d)\n", people[i].name, people[i].age);
    }

    return 0;
}
Bob (21)
Alice (34)
Carla (45)
Ending a program: exit and abort (recap)
  • exit(status) terminates the program cleanly: it flushes and closes open streams, runs functions registered with atexit, and returns status to the operating system.

  • abort() terminates immediately, without cleanup, typically after raising SIGABRT — reserved for unrecoverable situations.

  • Returning from main with a value is equivalent to calling exit with that value.