C Standard Library stdlib.h

Beginner
⏱️ 14 min read
📚 Updated: Jul 2026
🎯 5 Examples
<stdlib.h>

What You’ll Learn

<stdlib.h> is the “general utilities” header. It handles dynamic memory (malloc, free), ending your program (exit), turning text into numbers (strtol), random numbers (rand), and sorting arrays (qsort). If you have used stdio.h for I/O, stdlib.h is the natural next step for heap memory and helpers.

01

malloc

Allocate.

02

calloc

Zero fill.

03

free

Release.

04

strtol

Parse int.

05

exit

End program.

06

qsort

Sort array.

Definition and Usage

Stack arrays have a fixed size decided at compile time. malloc asks the operating system for memory at runtime and returns a void * you cast (in C, assignment to typed pointer works implicitly) to your data type. When finished, free returns that memory.

Beyond memory, stdlib.h offers process control (exit, abort, atexit), conversions (atoi, strtol, strtod), pseudo-random numbers (rand, srand), and algorithms (qsort, bsearch).

💡
Beginner Tip

Every malloc/calloc/realloc needs a matching free. Check for NULL after allocation failure. Prefer strtol over atoi when input might be invalid.

📝 Syntax

Include the header:

C
#include <stdlib.h>

Memory allocation

  • malloc(size) — allocate size bytes (uninitialized)
  • calloc(count, size) — allocate count * size bytes, zeroed
  • realloc(ptr, new_size) — resize an existing block
  • free(ptr) — release memory from malloc family

Process control

  • exit(status) — terminate program; flush stdio buffers
  • abort() — abnormal termination (may produce core dump)
  • atexit(func) — register function called on normal exit
  • EXIT_SUCCESS, EXIT_FAILURE — portable status codes

String conversion

  • atoi(str), atof(str) — simple conversions, no error detail
  • strtol(str, &end, base) — long integer with base and error pointer
  • strtod(str, &end) — double with error pointer

Other common functions

  • rand(), srand(seed), RAND_MAX
  • qsort(base, count, size, compare) — sort array
  • bsearch(key, base, count, size, compare) — binary search sorted array
  • abs(n), labs(n) — absolute value

Typical allocation pattern

C
int *arr = malloc(n * sizeof *arr);
if (arr == NULL) {
    fprintf(stderr, "Out of memory\n");
    exit(EXIT_FAILURE);
}
/* use arr */
free(arr);
arr = NULL;

Headers and linking

  • #include <stdlib.h> — linked automatically with the C library.
  • Memory functions use size_t from <stddef.h> (included indirectly).
  • Compile: gcc program.c -std=c11 -o program.

⚡ Quick Reference

FunctionCategoryPurpose
mallocMemoryAllocate bytes
callocMemoryAllocate + zero
reallocMemoryResize block
freeMemoryRelease block
strtolConvertString to long
exitProcessEnd with status
Array
malloc(n * sizeof *p)

Idiom

Parse
strtol(s, &end, 10)

Base 10

Exit
exit(EXIT_FAILURE)

On error

Dice
rand() % 6 + 1

1–6

Examples Gallery

Compile with gcc file.c -std=c11 -o out. All memory examples check for NULL and call free.

📚 Getting Started

Dynamic memory and conversions from the reference.

Example 1 — malloc and free (Dynamic Array)

From the reference: allocate five integers, fill them, print, then free.

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

int main(void) {
    size_t n = 5;
    size_t i;
    int *arr = malloc(n * sizeof *arr);

    if (arr == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        return EXIT_FAILURE;
    }

    for (i = 0; i < n; i++) {
        arr[i] = (int)(i + 1);
    }

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

    free(arr);
    arr = NULL;

    return EXIT_SUCCESS;
}

How It Works

malloc(n * sizeof *arr) allocates space for n ints. Contents are uninitialized—we assign values before reading. sizeof *arr avoids repeating the type. In C, casting malloc’s result is optional.

Example 2 — calloc (Zero-Initialized Array)

calloc sets every byte to zero—handy for counters or fresh buffers.

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

int main(void) {
    size_t n = 5;
    size_t i;
    int *counts = calloc(n, sizeof *counts);

    if (counts == NULL) {
        return EXIT_FAILURE;
    }

    counts[2] = 10;
    counts[4] = 3;

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

    free(counts);
    return EXIT_SUCCESS;
}

How It Works

calloc(5, sizeof(int)) is equivalent to malloc followed by zeroing memory. Unset slots stay 0 without explicit initialization.

📈 Practical Patterns

Growing buffers, safe parsing, and random numbers.

Example 3 — realloc (Grow an Array)

Start small, then expand when you need more elements.

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

int main(void) {
    size_t capacity = 2;
    size_t count = 0;
    size_t i;
    int *data = malloc(capacity * sizeof *data);
    int *tmp;
    int values[] = { 10, 20, 30, 40 };

    if (data == NULL) {
        return EXIT_FAILURE;
    }

    for (i = 0; i < 4; i++) {
        if (count == capacity) {
            capacity *= 2;
            tmp = realloc(data, capacity * sizeof *data);
            if (tmp == NULL) {
                free(data);
                return EXIT_FAILURE;
            }
            data = tmp;
        }
        data[count++] = values[i];
    }

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

    free(data);
    return EXIT_SUCCESS;
}

How It Works

Assign realloc to a temporary pointer. If it fails, the original block is still valid. Doubling capacity is a common growth strategy for dynamic arrays.

Example 4 — strtol (Better Than atoi)

Parse a string to integer and detect invalid input—something atoi cannot do.

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

int main(void) {
    const char *good = "12345";
    const char *bad = "12abc";
    char *end;
    long val;

    errno = 0;
    val = strtol(good, &end, 10);
    if (end == good || *end != '\0') {
        printf("'%s' is not a valid integer\n", good);
    } else {
        printf("Parsed '%s' -> %ld\n", good, val);
    }

    errno = 0;
    val = strtol(bad, &end, 10);
    if (end == bad || *end != '\0') {
        printf("'%s' is not a fully valid integer (stopped at '%s')\n",
               bad, end);
    } else {
        printf("Parsed '%s' -> %ld\n", bad, val);
    }

    /* Quick demo: atoi on same good string */
    printf("atoi(\"%s\") = %d\n", good, atoi(good));

    return EXIT_SUCCESS;
}

How It Works

strtol sets end to the first unparsed character. If that is not '\0', the whole string was not a valid integer. atoi from the reference works on clean input but hides errors. Use strtod for floating-point strings.

Example 5 — rand and srand (Roll a Die)

Seed the generator once, then produce random values in a range.

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

int main(void) {
    int i;

    srand((unsigned)time(NULL));

    printf("Rolling a die 5 times:\n");
    for (i = 0; i < 5; i++) {
        int roll = rand() % 6 + 1;
        printf("  Roll %d: %d\n", i + 1, roll);
    }

    printf("RAND_MAX on this system: %d\n", RAND_MAX);

    return EXIT_SUCCESS;
}

How It Works

srand(time(NULL)) seeds from the current time so runs differ. rand() % 6 + 1 yields 1–6. The old reference incorrectly showed rand(void)—the correct call is rand() with no arguments. Not suitable for security—use a crypto library for passwords or keys.

🚀 Common Use Cases

  • Dynamic arrays — grow lists when input size is unknown at compile time.
  • String buffers — build text piece by piece with realloc.
  • Config parsingstrtol/strtod for numeric settings.
  • Games and simulationsrand for dice, shuffles, or test data.
  • Sorting dataqsort on arrays of any element type.
  • Fatal errorsexit(EXIT_FAILURE) when recovery is impossible.

🧠 How stdlib.h Memory Works

1

Request heap memory

malloc/calloc ask the C runtime for a block.

Allocate
2

Use the pointer

Read and write through the returned address while it is valid.

Lifetime
3

free when done

Return the block so it can be reused; avoid leaks and double-free.

Release
=

Flexible programs

Data structures that grow with user input or file size.

📝 Notes

  • malloc does not zero memory; reading before writing is undefined behavior.
  • Multiplying sizes for malloc can overflow—check n > SIZE_MAX / sizeof(T) for large n.
  • Never free the same pointer twice; never use memory after free.
  • exit runs atexit handlers and flushes stdio; abort does not guarantee cleanup.
  • atoi/atof return 0 on failure—indistinguishable from a valid zero.
  • qsort requires a comparison function; array must be sortable in memory as one block.

⚡ Optimization

Frequent small malloc/free calls can be slow. Pool allocations, reuse buffers, or over-allocate with realloc in batches when profiling shows heap pressure. calloc costs slightly more than malloc due to zeroing—use malloc when you overwrite every byte anyway. Prefer stack arrays when size is small and known at compile time.

Conclusion

<stdlib.h> powers dynamic memory and everyday utilities in C. Learn malloc/free first, then calloc, realloc, and safe parsing with strtol. Pair with <stdio.h> for output and <string.h> for text manipulation.

Check every allocation, free every block once, and prefer explicit error handling over blind trust in atoi.

💡 Best Practices

✅ Do

  • Check malloc/calloc/realloc for NULL
  • Use malloc(n * sizeof *ptr) idiom
  • free every allocation exactly once
  • Set pointer to NULL after free
  • Use strtol/strtod with endptr
  • Return EXIT_SUCCESS / EXIT_FAILURE

❌ Don’t

  • Use memory after free (use-after-free)
  • Call free twice on the same pointer
  • Trust atoi for untrusted input
  • Forget to srand before expecting varied rand
  • Use rand for cryptography or security
  • Leak memory on every error path—free before return

Key Takeaways

Knowledge Unlocked

Five things to remember about stdlib.h

Memory, conversions, and utilities.

5
Core concepts
📚 02

free

Release.

Cleanup
📈 03

strtol

Safe parse.

Convert
📄 04

realloc

Grow array.

Resize
🌐 05

exit

Status code.

Process

❓ Frequently Asked Questions

stdlib.h is the C standard general utilities header. It provides dynamic memory functions (malloc, calloc, realloc, free), process control (exit, abort), string-to-number conversion (atoi, strtol, strtod), random numbers (rand, srand), sorting (qsort), searching (bsearch), and macros like EXIT_SUCCESS and RAND_MAX.
malloc(size) allocates size bytes with uninitialized contents. calloc(count, size) allocates count * size bytes and zeroes every byte. Use calloc when you want a clean slate—for example an array that should start at all zeros.
realloc(ptr, new_size) grows or shrinks a block previously allocated by malloc, calloc, or realloc. Use it when a dynamic array needs more room. If realloc fails it returns NULL and leaves the old block valid—assign to a temporary pointer or handle failure carefully.
atoi converts a string to int but reports no errors: invalid input returns 0 and you cannot tell if the string was "0" or garbage. Prefer strtol or strtod with an endptr to detect parse failures and overflow. atoi is fine only for quick demos with trusted input.
free(ptr) returns memory previously allocated by malloc, calloc, or realloc back to the system. Call free exactly once per allocation. After free, do not use the pointer unless you set it to NULL. Double-free and use-after-free are serious bugs.
rand() returns a pseudo-random integer from 0 to RAND_MAX. srand(seed) seeds the generator so the same seed produces the same sequence. Call srand once at program start—often with time(NULL) for variety. rand is not cryptographically secure.
Did you know?

malloc(0) is implementation-defined—it may return NULL or a unique non-null pointer that must not be dereferenced but can be passed to free. In practice, always treat zero-size allocation as a special case and avoid relying on this behavior.

Explore C Standard Library Headers

Continue with string.h or browse the library index.

Standard Library Index →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful