2016-08-30 3 views
0

-O3을 사용하여 C로 컴파일하고 Linux Fedora x64의 공유 라이브러리로 사용합니다. 나는 하나의 mallocs를 사용했다. 이 가족에서 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++; 
} 
+0

구현을 통해 달성하려는 목표는 무엇입니까? – Serge

+0

malloc을 많이 호출하지 마십시오 ... (빠른 메모리 사용시 스택이 가득 차 있지 않은 경우) –

+0

malloc의 성능에 병목 현상이 있습니까? 여러분은 malloc에 ​​의해 반환 된 포인터를 모두 사용할 수있는 단일 연속 메모리 블록에 대한 포인터로 자유롭게 해석 할 수 있다고 생각하게 만듭니다 (나는 당신의 속임수를 사용하여 ur_free_available 함수를 사용한다)? glibc 소스에서 malloc 구현을 확인 했습니까? – Serge

답변

0

Breafly는 변수 addr가 초기화되지 않는 기능 ur_free_available를 찾고 있지만, 당신 방어 적이기는 임의의 메모리 영역을 손상. 그런 다음 동일한 초기화되지 않은 포인터를 사용하여 무언가를 반환하려고합니다.

관련 문제