简体   繁体   English

由于未知原因造成的细分错误

[英]Segmentation fault for a weird unknown reason

I get a segmentation fault (core dumped) in the following peace of code (I'm implementing malloc() , free() and realloc() ): 在以下和平代码中,我遇到了segmentation fault (core dumped) (我正在实现malloc()free()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. 现在,您假设它将打印aaabbb ,它只是在X行执行printf()之后立即宣布分段错误。如果我键入“ printf(“ a”)“而不是当前的printf()它根本不会显示“ a”。 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. 变量head是该文件中的静态变量。 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. 完整的代码在这里可用但我怀疑它是否相关,该程序至少应该打印“ aaa”或“ bbb”,但它不会这样做。 Any idea? 任何想法? I'm really desperate. 我真的很绝望。

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 注意-您的mm.h包含我在同一文件中包含的代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM