nemo
nemo

Reputation: 35

malloc, free: error invalid next size(fast)

I currently learning c and then ran into free() and malloc(). So there is this small program to toy aroung with malloc and free.

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

int main(int argc, char *argv[]) {
    char *char_ptr; // A char pointer
    int *int_ptr; // An integer pointer
    char *char_ptr1;
    int mem_size;

    if (argc < 2)// If there aren't command-line arguments,
        mem_size = 50; // use 50 as the default value.
    else
        mem_size = atoi(argv[1]);

    printf("\t[+] allocating %d bytes of memory on the heap for char_ptr\n", mem_size);
    char_ptr = (char *) malloc(mem_size); // Allocating heap memory

    if(char_ptr == NULL) { // Error checking, in case malloc() fails
        fprintf(stderr, "Error: could not allocate heap memory.\n");
    exit(-1);
    }

    strcpy(char_ptr, "This is memory is located on the heap.");
    printf("char_ptr (%p) --> '%s'\n", char_ptr, char_ptr);

    printf("\t[+] allocating 12 bytes of memory on the heap for int_ptr\n");
    int_ptr = (int *) malloc(12); // Allocated heap memory again

    if(int_ptr == NULL) { // Error checking, in case malloc() fails
        fprintf(stderr, "Error: could not allocate heap memory.\n");
        exit(-1);
    }

    *int_ptr = 31337; // Put the value of 31337 where int_ptr is pointing.
    printf("int_ptr (%p) --> %d\n", int_ptr, *int_ptr);


    printf("\t[-] freeing char_ptr's heap memory...\n");
    free(char_ptr); // Freeing heap memory

    printf("\t[+] allocating another 15 bytes for char_ptr\n");
    char_ptr1 = (char *) malloc(15); // Allocating more heap memory

    if(char_ptr == NULL) { // Error checking, in case malloc() fails
        fprintf(stderr, "Error: could not allocate heap memory.\n");
        exit(-1);
    }
    else printf("succeded in allocation, [pointer] %p\n", char_ptr);


    strcpy(char_ptr1, "new memory");
    printf("char_ptr (%p) --> '%s'\n", char_ptr1, char_ptr1);

    printf("\t[-] freeing int_ptr's heap memory...\n");
    free(int_ptr); // Freeing heap memory
    printf("\t[-] freeing char_ptr's heap memory...\n");
    free(char_ptr1); // Freeing the other block of heap memory
}

So, if I allocate a rather large memoryspace for the char_ptr it works well.

But what confuses me, is that for small values it doesn't work. I get the value: error: "free() invalid next size(fast)".

From what I've read in other posts, this occures when one wants to free memory that has not been allocated, which is not the case in my example.

So in what way is the allocation of char_ptr related to char_ptr1's freeing ?

Upvotes: 1

Views: 2408

Answers (3)

Montaldo
Montaldo

Reputation: 863

A bit of background.

In general malloc receives an argument that tells him how many space you wish to allocate and returns you the pointer to this memory block.

type * var = malloc(sizeof(type) * length);

type can be any type that you wish to be allocated on the heap, int, char etc.

Let's look at your code. This line for example:

char_ptr = (char *) malloc(mem_size); // Allocating heap memory

Here you want to allocate an array of characters with lenght = mem_size. This code is valid because sizeof(char) is 1. It requires 1 byte to store a character.

However, a better way of writting this would be:

char_ptr = malloc(sizeof(char) * mem_size); // Allocating heap memory

This feels better and you stick to the same format eventhough the sizeof(char) is redundant in a way. Also, do not cast the outcome of a malloc operation. Leave this to be promoted to you specified type. See this post here.

Back to your question:

So in what way is the allocation of char_ptr related to char_ptr1's freeing ?

It is not in this case. I feel you mixed up the guard pointer, being char_ptr instead of the just allocated char_ptr1.

     |
     v

if(char_ptr1 == NULL) { // Error checking, in case malloc() fails
    fprintf(stderr, "Error: could not allocate heap memory.\n");
    exit(-1);
}

Upvotes: 0

unwind
unwind

Reputation: 399703

If you write more data than you allocated room for, you get undefined behavior.

Upvotes: 0

Dirk
Dirk

Reputation: 31053

If you allocate only a small buffer, code like

strcpy(char_ptr, "This is memory is located on the heap.");

may overflow the allocated area (you need to allocate a buffer of at least size 39 bytes for this string). In particular, you might by overwriting parts of the internal data structures used by malloc itself to keep track of the allocations. Make sure, that the malloc'ed space is large enough to accomodate all the data you put into it.

Similar problems may occur with the int_ptr. Your size of 12 is odd but should be safe (on "common" machines). Better, though, would be:

int_ptr = malloc(sizeof(int));

Upvotes: 3

Related Questions