C programming - basic memory management system with leak detection

This reconstructed code implements a basic memory management system with leak detection. Here's an explanation of the different parts:


1. `MemoryNode` structure: This defines a node in a linked list that tracks memory allocations. Each node contains a pointer to the allocated memory, its size, and a pointer to the next node.


2. `custom_malloc` function:

   - Handles zero-sized allocations by returning NULL.

   - Allocates memory using the standard `malloc`.

   - Creates a new `MemoryNode` to track the allocation.

   - Adds the new node to the front of the linked list.


3. `custom_free` function:

   - Traverses the linked list to find the node corresponding to the pointer being freed.

   - Removes the node from the list and frees both the allocated memory and the tracking node.

   - If the pointer is not found in the list, it prints an error message.


4. `check_leaks` function:

   - Traverses the linked list of allocations.

   - If the list is empty, it reports no leaks.

   - If there are nodes in the list, it reports each as a leak, printing the address and size.

   - Frees all remaining allocations and their tracking nodes.


5. `main` function:

   - Demonstrates usage by allocating memory, freeing some of it, and then checking for leaks.


This system helps prevent memory leaks by tracking all allocations and providing a way to check for unfreed memory. However, it's important to note that this is a simplified implementation and may not be suitable for production use without further refinement and error handling.

__________

Code:

// Structure to represent a memory allocation node

typedef struct MemoryNode {

    void *ptr; // Pointer to the allocated memory

    size_t size; // Size of the allocated memory

    struct MemoryNode *next; // Pointer to the next node

} MemoryNode;


// Global variable to store the head of the linked list

MemoryNode *head = NULL;


// Custom malloc function

void *custom_malloc(size_t size) {

    // Handle zero-sized allocations

    if (size == 0) {

        return NULL;

    }


    // Allocate memory

    void *ptr = malloc(size);

    if (ptr == NULL) {

        fprintf(stderr, "Memory allocation failed!\n");

        return NULL;

    }


    // Create a new node and add it to the linked list

    MemoryNode *new_node = malloc(sizeof(MemoryNode));

    if (new_node == NULL) {

        fprintf(stderr, "Memory allocation for tracking failed!\n");

        free(ptr);

        return NULL;

    }


    new_node->ptr = ptr;

    new_node->size = size;

    new_node->next = head;

    head = new_node;


    return ptr;

}


// Custom free function

void custom_free(void *ptr) {

    if (ptr == NULL) {

        return;

    }


    MemoryNode *current = head;

    MemoryNode *previous = NULL;


    // Traverse the linked list to find the node to free

    while (current != NULL) {

        if (current->ptr == ptr) {

            // Remove the node from the list

            if (previous == NULL) {

                head = current->next;

            } else {

                previous->next = current->next;

            }


            // Free the memory and the node

            free(current->ptr);

            free(current);

            return;

        }

        previous = current;

        current = current->next;

    }


    fprintf(stderr, "Attempted to free untracked pointer: %p\n", ptr);

}


// Function to check for memory leaks

void check_leaks() {

    MemoryNode *current = head;


    if (current == NULL) {

        printf("No memory leaks detected.\n");

        return;

    }


    printf("Memory leaks detected:\n");

    while (current != NULL) {

        printf("Leaked memory at %p, Size: %zu bytes\n", current->ptr, current->size);

        MemoryNode *temp = current;

        current = current->next;

        free(temp->ptr);

        free(temp);

    }


    head = NULL;

}


// Main function to demonstrate usage

int main() {

    int *data1 = (int *)custom_malloc(sizeof(int) * 5);

    char *data2 = (char *)custom_malloc(sizeof(char) * 10);


    custom_free(data1);

    // Intentionally not freeing data2 to create a leak


    check_leaks();


    return 0;

}

Comments

Popular posts from this blog

Roles in software / IT and ITES industries, categorized into roles better suited for freelancers and roles suited for full-time employees

What is monkey testing in software testing and how is it helpful ?