C语言 由于奇怪的未知原因而出现的分段错误



我在以下代码和平中得到了一个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 %pn", curr, ptr);
     if(curr == ptr)
     {
         printf("aaa");
     }
     else
     {
         printf("bbb");
     }
     /*Some more code that actually frees the pointer and not relevant here*/
 }

现在,你会假设它会打印aaabbb,它只是在执行第 X 行的printf()后立即宣布分段错误。如果我输入"printf("a"("而不是当前printf()它根本不会打印"a"。这真的很奇怪。它打印:

curr is 0x86be000 and ptr is 0x86be000

然而,它只会退出并立即抛出分段错误。变量head是该文件中的静态变量。我真的很想知道问题出在哪里,这真的很奇怪。下面是头文件中的语句:

void free(void* ptr);

就这么简单,你觉得这里有什么问题吗?完整的代码在这里可用,但我怀疑它是否相关,程序至少应该打印"aaa"或"bbb",但它没有这样做。知道吗?我真的很绝望。

以下代码符合警告,但执行完美

#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 %pn", curr, ptr);
        if(curr == ptr)
        {
                printf("aaan");
        }
        else
        {
                printf("bbbn");
        }
        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!");
        printf("About to freen");
        free(str);
        printf("free: OK!n");
}

输出:

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

注意 - 你的 mm.h 包括我在同一文件中包含的代码

相关内容

  • 没有找到相关文章

最新更新