0

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.

Jack
  • 111
  • 1
  • 1
  • 6
  • 4
    Since you don't print a newline or use `fflush`, your printf output just wasn't flushed out. You should use newlines on each print statement if you are debugging with them. – JS1 Dec 22 '14 at 09:53
  • @JS1 I don't get it, you're basically saying I should just add a '\n' or use 'fflush(stdout)' ? Not working with either. – Jack Dec 22 '14 at 09:58
  • So, after you change your `aaa` and `bbb` to add newlines, you don't see either in your output but you still see the previous printf output? I'm not saying it will fix your segv, just that you should see `aaa` or `bbb`. The segv probably is happening later on. – JS1 Dec 22 '14 at 10:00
  • @JS1 Oh, adding '\n' to the 'aaa' and 'bbb', YES, it is working ! THANK YOU VERY MUCH ! – Jack Dec 22 '14 at 10:09
  • Then what is it that you were complaining about seg fault? – Gopi Dec 22 '14 at 10:10
  • Maybe I am reading your code wrong, but it looks like your malloc is returning a pointer to you control structure, which then gets trashed when you strcpy on top of it... You probably want to return something like ptr + size of(metadata-block) and adjust free in the same way... – forsvarir Dec 22 '14 at 10:13
  • Word of advice: always use different names for `user defined` library _equivalent_ functions, e.g., use `my_free()`. Saves a lot of pain in future. – Sourav Ghosh Dec 22 '14 at 10:42

1 Answers1

0

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

Kavindu Dodanduwa
  • 12,193
  • 3
  • 33
  • 46
  • Indeed, after adding '\n' it worked. Thank you, I didn't know it was that critical in unix. – Jack Dec 22 '14 at 10:13
  • @kcdod Nice effort. However, if you can state what was the problem in OP's code and what changes you made to resolve the issues, it will be very helpful to future visitors. Thank you. :-) – Sourav Ghosh Dec 22 '14 at 10:44