Search code examples
cmemorymallocallocationrealloc

Is this an acceptable way to deallocate memory in c?


I have a function that reads a file and allocates memory for the files contents and assigns the files contents to a pointer and then returns the pointer. I then use a loop to loop over the string and print each character using pointer arithmetic.

I'm pretty sure I could/should use realloc to reallocate less memory each iteration as opposed to tracking the iterations with a counter but I'm not sure exactly how to implement it.

So instead at the end of the code when I call free() I subtracted the counter from the pointer variable to deallocate the address that the contents pointer originally pointed to.

Below is the code I used to read the file as well as the main function where my loop is at:

char *read_file(const char *filename) {
    FILE *fp = fopen(filename, "r");
    if (fp == NULL) {
        perror("Failed to open file");
        exit(EXIT_FAILURE);
    }

    // Obtain information about the file
    struct stat st;
    if (fstat(fileno(fp), &st) != 0) {
        perror("Failed to get file information");
        exit(EXIT_FAILURE);
    }
    size_t file_size = st.st_size;

    // Allocate a buffer to hold the contents of the file
    char *buffer = (char *) malloc(file_size + 1);
    if (buffer == NULL) {
        perror("Failed to allocate memory");
        exit(EXIT_FAILURE);
    }

    // Read the contents of the file into the buffer
    size_t bytes_read = fread(buffer, 1, file_size, fp);
    buffer[bytes_read] = '\0';

    // Close the file and return the buffer
    fclose(fp);
    return buffer;
}




int main() {
    char *contents = read_file("testNote.txt");
    int counter = 0;

    while (*contents != '\0') {

        printf("%c", *contents);

        ++counter;
        ++contents;
    }

    free(contents - counter);

    return 0;
}

As far as I can tell after experimenting this is working the way I'm thinking it is, but I just want to make sure I'm not doing anything harmful here


Solution

  • What you're doing will work. Each time you increment contents, you also increment counter, so contents - counter gives you the original pointer that you can free.

    Of course, a better way of doing this would be to use a temporary pointer to increment through the allocated memory so you can use the original to free.

    int main() {
        char *contents = read_file("testNote.txt");
        char *tmp = contents;
    
        while (*tmp != '\0') {
    
            printf("%c", *tmp);
    
            ++tmp;
        }
    
        free(contents);
    
        return 0;
    }