ZetCode

C memset function

last modified April 8, 2025

Memory initialization is fundamental in C programming, and memset is a key function for setting memory blocks to specific values. This tutorial covers memset in depth, including its syntax, usage, and potential pitfalls. We'll explore practical examples and discuss safer alternatives for critical applications. Understanding memset helps optimize memory operations while maintaining program safety and reliability.

What Is memset?

The memset function fills a block of memory with a specified value. It's declared in string.h and takes three parameters: the pointer to the memory block, the fill value, and the number of bytes to set. memset operates at byte level, making it efficient for bulk initialization. For security-sensitive code, consider memset_s which provides runtime constraints checking.

Basic memset Usage

This example demonstrates initializing an array with zeros using memset.

basic_init.c
#include <stdio.h>
#include <string.h>

int main() {
    char buffer[50];

    // Initialize buffer with zeros
    memset(buffer, 0, sizeof(buffer));

    printf("Buffer contents: ");
    for (size_t i = 0; i < sizeof(buffer); i++) {
        printf("%d ", buffer[i]);
    }
    printf("\n");

    return 0;
}

Here, memset sets all 50 bytes of buffer to zero. The sizeof operator ensures we initialize the entire array. This is a common pattern for clearing buffers before use. Note that memset works with any memory block, not just character arrays. Always specify the correct size to prevent buffer overflows.

Initializing Structures with memset

memset can efficiently initialize entire structures, as shown here.

struct_init.c
#include <stdio.h>
#include <string.h>

typedef struct {
    int id;
    char name[20];
    float score;
} Student;

int main() {
    Student s1;

    // Initialize structure to zeros
    memset(&s1, 0, sizeof(Student));

    printf("Initialized Student:\n");
    printf("ID: %d\n", s1.id);
    printf("Name: %s\n", s1.name);
    printf("Score: %.1f\n", s1.score);

    return 0;
}

This example initializes a Student structure using memset. The sizeof operator ensures we set all bytes in the structure to zero. This method is faster than field-by-field initialization for large structures. Note that this works for simple structures without pointers to dynamically allocated memory. Padding bytes are also initialized.

Setting Non-Zero Values

This example demonstrates setting all elements of an array to a specific value.

array_init.c
#include <stdio.h>
#include <string.h>

int main() {
    int numbers[10];
    
    // Set all elements to 0xFF
    memset(numbers, 0xFF, sizeof(numbers));

    printf("Array contents: ");
    for (size_t i = 0; i < sizeof(numbers)/sizeof(numbers[0]); i++) {
        printf("%08X ", numbers[i]);
    }
    printf("\n");

    return 0;
}

Here, memset sets all bytes in the integer array to 0xFF. Note that this sets each byte, not each array element, to the specified value. For integer arrays, this results in each element being 0xFFFFFFFF (for 32-bit integers). This technique is useful for creating specific bit patterns in memory. Be aware of the byte-level operation when working with non-character data types.

Safe Alternative: memset_s

This example demonstrates the safer memset_s function available in C11.

safe_init.c
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <string.h>

int main() {
    char sensitive[100];
    
    // Secure initialization with bounds checking
    errno_t result = memset_s(sensitive, sizeof(sensitive), 0, sizeof(sensitive));

    if (result != 0) {
        printf("Error: Buffer size mismatch or invalid parameters\n");
        return 1;
    }

    printf("Buffer securely initialized\n");
    return 0;
}

memset_s adds bounds checking and returns an error if the destination size is incorrect. This helps prevent buffer overflows. The function returns zero on success and non-zero on failure. While not universally available, it's recommended for security-critical code when targeting C11 or later standards with bounds-checking support. It's particularly useful for clearing sensitive data.

The macro __STDC_WANT_LIB_EXT1__ is defined as 1 to explicitly indicate that the program wants to use optional extensions from the C11 standard library. Without this macro, certain safer functions, including memset_s, may not be made available by the compiler. This feature allows developers to selectively enable additional functionality to improve security and reliability in their programs.

Clearing Strings with memset

This example shows how to clear a string using memset.

string_clear.c
#include <stdio.h>
#include <string.h>

int main() {
    char password[50] = "MySecretPassword123";
    
    printf("Before clear: %s\n", password);
    
    // Securely clear the password
    memset(password, 0, sizeof(password));
    
    printf("After clear: %s\n", password);

    return 0;
}

Here, memset securely clears a password string by setting all bytes to zero. This is important for sensitive data that shouldn't remain in memory. The sizeof operator ensures we clear the entire buffer, not just the string contents. Note that compilers may optimize away memset calls in some cases, making memset_s preferable for security.

Best Practices for Using memset

Source

C memset Documentation

This tutorial has explored the memset function, from basic usage to advanced considerations. While powerful, always use memory operations carefully to prevent security vulnerabilities and undefined behavior in your programs.

Author

My name is Jan Bodnar, and I'm a dedicated programmer with a deep passion for coding. Since 2007, I've been sharing my expertise through over 1,400 articles and 8 e-books. With more than a decade of teaching experience, I strive to make programming accessible and engaging.

List C Standard Library.