有人可以解释我的内存池出了什么问题吗?

标签 c memory-management glibc

我使用 -O3 在 C 中编译并作为 Linux Fedora x64 上的共享库。之后我使用了一些 malloc。似乎当我使用 wmemcpy 和这个系列中的其他函数时,一个内存的变化会导致其他内存的变化...... 我可能会违反内存大小吗?或者问题出在我的实现上?

提前致谢!

char* ur_free_available(struct memory_pool* pool, uint64_t sz)
{
    uint64_t size =  sz + sizeof(struct _MyPage);
    if(pool->free_pos > 0)
    {
        if(pool->free_blocks[pool->free_pos - 1].pNext - pool->free_blocks[0].pNext > size)
        {
            uint64_t i, j;
            char *addr;
            struct _MyPage mpg;
            for(i = 1; i < pool->free_pos; ++i)
            {
                if(pool->free_blocks[i].pNext - pool->free_blocks[0].pNext > size)
                {
                    mpg.pPrev = NULL;
                    mpg.pNext = pool->free_blocks[i-1].pNext;
                    break;
                }

            }
            pool->free_blocks[0].pPrev = NULL;
            for(j = i; j < pool->free_pos; ++j)
            {                   
                    if(j > 0)
                        pool->free_blocks[j-i].pPrev = pool->free_blocks[j-1].pPrev;
                    pool->free_blocks[j-i].pNext = pool->free_blocks[j].pNext;                                      
            }
            pool->free_pos -= i;
            pool->free_pos++;
            memcpy(addr,(char*)&mpg, sizeof(mpg));
            return &addr[0] + sizeof(struct _MyPage);
        }
    }
    return NULL;
}


char* ur_mem_alloc(struct memory_pool* pool, uint64_t sz)
{
    char *addr;
    struct _MyPage mpg;
    uint64_t size = sz  + sizeof(mpg);
    uint64_t j = 0, c, op;
    if(pool->init_pos_is != 7)
    {
        //bzero(pool, sizeof(pool));        
        pool->init_pos_is = 7;
        pool->free_pos = 0;
        pool->hp_position = 0;
        pool->st_position = 0;
        mpg.pPrev = NULL;   
        for(c = 0; c < HP_CNT; c++)
            pool->_extramem[c] = NULL;
        pool->free_blocks[0].pNext = NULL;
        //pool->_bytes = malloc(ST_MYPAGE_NO*ST_MYPAGE_SIZE);
        //pthread_mutex_lock(&llk1);
        _mpool = pool;
        //pthread_mutex_unlock(&llk1);
        atexit(equit);
    }

    if((addr = ur_free_available(pool, size)) != NULL)      
    {
        return &addr[0];
    }
    op = pool->hp_position;
    if(size + (ST_MYPAGE_SIZE * pool->st_position) > ST_MYPAGE_NO * ST_MYPAGE_SIZE)
    {
        uint64_t i;     
        for(i = 0; i < HP_CNT; ++i)
        {
            if(size < (pow(8, i)-pool->hp_position)*HP_MYPAGE_SIZE)             
            {
                j = i;              


                if(pool->_extramem[i] == NULL)
                {       
                    pool->hp_position = 0;  
                    pthread_mutex_lock(&llk2);
                    pool->_extramem[i] = (char*)malloc((uint64_t)pow(8, i) * HP_MYPAGE_SIZE);
                    pthread_mutex_unlock(&llk2);
                }
                break;          
            }

        }

        addr = &pool->_extramem[j][pool->hp_position*HP_MYPAGE_SIZE];
        mpg.pPrev = (struct _MyPage*)&pool->_extramem[j][op*HP_MYPAGE_SIZE];
        //printf("j %u %u %u\n", j, (uint64_t)size, (uint64_t)(pow(8, i-1))*HP_MYPAGE_SIZE);
        pool->hp_position += floor(size/HP_MYPAGE_SIZE) + 1;        
        mpg.pNext = (struct _MyPage*)&pool->_extramem[j][pool->hp_position*HP_MYPAGE_SIZE];

        memcpy(addr,(char*)&mpg, sizeof(mpg));
        return &addr[0] + sizeof(struct _MyPage);
        //
    }
    else
    {
        if(pool->st_position != 0)
        {
            mpg.pPrev = (struct _MyPage*)&pool->_extramem[j][(pool->hp_position)];
        }
        mpg.pNext = NULL;
        pool->st_position += floor(size/ST_MYPAGE_SIZE);
        addr = &pool->_bytes[(uint64_t)(pool->st_position-floor(size/ST_MYPAGE_SIZE)) * ST_MYPAGE_SIZE];
        memcpy(addr,(char*)&mpg, sizeof(mpg));
        return &addr[0] + sizeof(struct _MyPage);
    }

}
void ur_mem_free(struct memory_pool* pool, char *addr)
{
    if(addr == NULL) return;

    pool->free_blocks[pool->free_pos].pPrev = pool->free_blocks[pool->free_pos].pNext;
    pool->free_blocks[pool->free_pos].pNext = (struct _MyPage*)(addr - sizeof(struct _MyPage));
    pool->free_pos++;
}

最佳答案

简单地查看函数ur_free_available,变量addr未初始化,但您对它进行memcpy破坏了随机内存区域。然后,您尝试使用相同的未初始化指针返回某些内容。

关于有人可以解释我的内存池出了什么问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39232889/

相关文章:

c - glibc 检测到错误 - id3Tag

c - 如何检查套接字的接收或发送点是否已关闭

c - 如何生成遵循特定顺序的三个子进程?

c - 我的 C 代码没有在 Visual Studio 2017 上编译,并且一直给我一个错误,说它找不到特定的文件?

java - 方法区和 PermGen

c - glibc中printf()的跟踪代码

c - 一个长选项,其 "val"恰好是 `0` ?

postgresql自定义函数的便利性VS plpgsql

ios - ARC下iOS内存管理方法

multithreading - SMP 并行的内存管理瓶颈