Segmentation fault for a weird unknown reason

217 views Asked by At

I get a segmentation fault (core dumped) in the following peace of code (I'm implementing malloc(), free() and realloc()):

void free(void* ptr)
{
     void* curr = head;
     void* before = NULL;
     int isLegal = 0;
     /*Line X*/printf("curr is %p and ptr is %p\n", curr, ptr);
     if(curr == ptr)
     {
         printf("aaa");
     }
     else
     {
         printf("bbb");
     }
     /*Some more code that actually frees the pointer and not relevant here*/
 }

Now, you'd assume that it'd print aaa or bbb, it just announces a segmentation fault right after performing the printf() in line X. If I type "printf("a")" instead of the current printf() it won't print 'a' at all. That is really weird. It prints:

curr is 0x86be000 and ptr is 0x86be000

and yet it would just exit and throw a segmentation fault right after. The variable head is a static variable in that file. I really want to know where the problem is, it's really weird. Here's the statement from the header file:

void free(void* ptr);

As simple as that, do you see any problem in here? The full code is available here but I doubt it's related, the program should, at least, print either 'aaa' or 'bbb', and it doesn't do that. Any idea? I'm really desperate.

1

There are 1 answers

2
Kavindu Dodanduwa On BEST ANSWER

Following code complied with warnings but did execute perfectly

#include <unistd.h>
typedef struct metadata_block* p_block;

typedef struct metadata_block
{
        size_t size;
        p_block next;
        int free;
}metadata_block;

void* malloc(size_t size);
void free(void* ptr);
void* realloc(void* ptr, size_t size);

//THE MAIN CODE IS AT THE BOTTOM//
#include <stdio.h>

static p_block head = NULL;

void* malloc(size_t size)
{
        void* ptr;
        int isOk = 1;
        int temp = 0;
        p_block curr = head;
        if(size <= 0)
        {
                return NULL;
        }
        if(curr)
        {
                while(curr->next && isOk)
                {
                        if(curr->free && size <= curr->size)
                        {
                                isOk = 0;
                        }

                        if(isOk)
                        {
                                curr = curr->next;
                        }
                }

                if(isOk) //what will happen if there isn't one free and big enough
                {
                        ptr = sbrk(size + sizeof(metadata_block));
                        if((int)ptr <= 0)
                                return NULL;
                        ((p_block)(ptr))->size = size;
                        ((p_block)(ptr))->next = NULL; //next run it's the real next.
                        ((p_block)(ptr))->free = 0;

                        return (ptr + sizeof(metadata_block));
                }
                else
                {
                        if(curr->next)
                        {
                                ptr = curr;
                                if(curr->size == size || size > (curr->size - sizeof(metadata_block) - 1)) //not enough room for another block of memory
                                {
                                        ((p_block)(ptr))->free = 0;
                                        return (ptr + sizeof(metadata_block));
                                }

                                temp = curr->size;
                                ((p_block)(ptr))->size = size;
                                ((p_block)(ptr))->free = 0;
                                ((p_block)(ptr + sizeof(metadata_block) + size))->next = curr->next;
                                ((p_block)(ptr))->next = ptr + sizeof(metadata_block) + size;
                                ((p_block)(ptr + sizeof(metadata_block) + size))->size = temp - size;
                                ((p_block)(ptr + sizeof(metadata_block) + size))->free = 1;

                                return (ptr + sizeof(metadata_block));
                        }
                        else
                        {
                                ptr = curr;
                                if((int)sbrk(size - curr->size) > 0)
                                {
                                        ((p_block)(ptr))->size = size;
                                        ((p_block)(ptr))->next = NULL; //next run it's the real next.
                                        ((p_block)(ptr))->free = 0;

                                        return (ptr + sizeof(metadata_block));
                                }
                                return NULL;
                        }
                }
        }
        else
        {
                ptr = sbrk(size + sizeof(metadata_block));
                if((int)ptr <= 0)
                        return NULL;
                head = ptr;
                ((p_block)(ptr))->size = size;
                ((p_block)(ptr))->next = NULL;
                ((p_block)(ptr))->free = 0;
        }


        return ptr;
}

void free(void* ptr)
{
        void* curr = head;
        void* before = NULL;
        int isLegal = 0;
        printf("curr is %p and ptr is %p\n", curr, ptr);
        if(curr == ptr)
        {
                printf("aaa\n");
        }
        else
        {
                printf("bbb\n");
        }
        if(curr && ptr)
        {
                while(curr && !isLegal)
                {
                        if(((p_block)(ptr)) == ((p_block)(curr))->next)
                        {
                                before = curr;
                                isLegal = 1;
                                curr = ((p_block)(curr))->next;
                        }
                        else
                        {
                                curr = ((p_block)(curr))->next;
                        }
                }

                if(isLegal)
                {
                        curr = curr - sizeof(metadata_block);

                        if(((p_block)(curr))->next)
                        {
                                ((p_block)(curr))->free = 1;
                        }
                        else
                        {
                                sbrk(0-(((p_block)(curr))->size + sizeof(metadata_block)));
                                ((p_block)(before))->next = NULL;
                        }
                }
        }
}

void* realloc(void* ptr, size_t size)
{
        void* ptr2 = malloc(size);
        int i;
        for(i = 0 ; i < size ; i++)
        {
                *((char*)(ptr2 + i)) = *((char*)(ptr + i));
        }

        free(ptr);

        return ptr2;
}


int main()
{
        printf("I'm in.\n");
        char * str = malloc(10);
        printf("After Malloc()\n");
        void * ptr = (void *) str;
        void * ptr2;
        if(!str)
        {
                printf("Fail.\n");
        }
        strcpy(str,"TEST!\0");
        printf("About to free\n");
        free(str);
        printf("free: OK!\n");
}

Output :

I'm in.                                                   
After Malloc()                                            
About to free                                             
curr is 0x1049000 and ptr is 0x1049000                    
aaafree: OK!  

note - Instaed of your mm.h include I included codes in same file