2012-05-12 3 views
2

나는 아직도 C에서 녹슬지 만 나는 이것을 알아 내지 못하고있다. 내가 뭘 하려는지 할당을 추적하고 free()에 대한 누락 된 호출을 디버깅 할 수 있도록 내 자신의 malloc을 구현하는 것입니다. 이 같은 헤더가 있습니다커스텀 malloc에 ​​디버그 헤더 추가하기

typedef struct MemoryInfo { 
    mem_Kind kind; 
    unsigned int id; 
    struct MemoryInfo* prev; 
    struct MemoryInfo* next; 
} MemoryInfo; 

을 그리고 내 사용자 지정의 malloc은 다음과 같이 보입니다 :

void* my_malloc(mem_Kind kind, unsigned int size) { 
    MemoryInfo* mem; 

    allocCount++; 
    mem = (MemoryInfo*)malloc(sizeof(MemoryInfo) + size); 
    mem->id = id; 
    mem->kind = kind; 
    // set prev/next... 

    return mem + sizeof(MemoryInfo); // return pointer to memory after header 
} 

을하지만 매우 빠르게 꽤 무섭게 불면 때문에 나는 분명 내 포인터 연산이 잘못 얻고있다. 그러나 만약 내가 void* memory 내 구조체의 끝 부분에 추가하고 다른 malloc 다음 잘 할 것 같다, 그 문제는 내가 실제로 my_free에서 헤더를 찾을 수 없다는 것입니다. 기본적으로 헤더를 앞에 추가하려고하므로 헤더를 무료로 가져 오기 위해 역방향 포인터 연산을 수행 할 수 있습니다.

void my_free(void* memory) { 
    MemoryInfo* mem = memory - sizeof(MemoryInfo); // not correct either 
    allocCount--; 
    free(mem); 
} 

여기서 내가 뭘 잘못하고 있니?

답변

1

포인터에 추가하는 데 문제가 있다고 생각합니다. 그것은 다음과 같이되어야합니다 :

return (char*)mem + sizeof(MemoryInfo); // return pointer to memory after header 

void my_free(void* memory) { 
    MemoryInfo* mem = (MemoryInfo*)((char*)memory - sizeof(MemoryInfo)); // not correct either 
    allocCount--; 
    free(mem); 
} 

을 그건 그렇고. 이 프로그램을보십시오.

#include <stdio.h> 

typedef struct MemoryInfo { 
    int kind; 
    unsigned int id; 
    struct MemoryInfo* prev; 
    struct MemoryInfo* next; 
} MemoryInfo; 



int main() 
{ 
    MemoryInfo* ptr = 0; 

    printf("sizeof: %d\n",sizeof(MemoryInfo)); 
    printf("%d\n",ptr+3); 
    return 0; 
} 

MemoryInfo를 가리키는 포인터에 3을 추가했지만 그 값은 3 * sizeof (MemoryInfo)가됩니다.

+0

흥미 롭습니다. 매력처럼 작동합니다! void *가 작동하지 않는 이유를 설명 할 수 있습니까? char *로 캐스팅해야합니까? –

+0

제발,보세요 http://stackoverflow.com/a/1666247/184968 –

+0

아, 봐요. 감사. –

0

포인터 연산이 잘못되었습니다. ptr+1에서 +1은 이미 올바른 증분 (sizeof * ptr)을 사용합니다. ptr이 char 포인터 인 경우에는 sizeof *ptr만큼 증가시켜야하지만 그렇지 않은 경우가 있습니다.

void *my_malloc(mem_Kind kind, unsigned int size) { 
    MemoryInfo mem; 

    allocCount++; 
    mem = malloc(sizeof *mem + size); 
    mem->id = id; 
    mem->kind = kind; 
    // set prev/next... 

    return mem + 1; // return pointer to memory after header 
} 


void my_free(void *memory) { 
    MemoryInfo *mem = memory; // not correct either 
    mem -= 1; 
    allocCount--; 
    free(mem); 
} 

또한, 고려가의 malloc을 (하시기 바랍니다) 친구는 모든 객체에 적합하며, 개체에 대한 자연 경계에 정렬되어야 포인터를 반환해야합니다. (이것은 32 비트, 64 비트 또는 플랫폼이 지시하는 것일 수 있음) sizeof (int) == 2 및 sizeof (void *) == 8에서는 크기가 실패 할 수 있습니다.

0

좋은 방법은 다음과 같이 정의이다 (그러나 운이 좋게, 아주 드문 경우를 보인다) :

struct some_struct { 
    size_t data_size; 
    struct some_struct *next, *prev; 
    void * struct_data[]; 
} 

와 같은 우리가 그것을 :

struct some_struct *get_some_struct (void *buf,size_t buflen,struct some_struct **next){ 
    *next=0; 
    struct some_struct *s=(struct some_struct *)buf; 
    if (s && buflen < sizof(*s) + s->data_size) 
    *next = (char*)s + s->data_size; 
    return s; 
    else 
    return 0; 
} 

그래서, 당신은을 통해 반복해야하는 경우 구조체를 사용하면 버퍼의 다음 구조체의 오프셋을 올바르게 얻을 수 있습니다. 그냥 당신이 접근하기를 바랍니다. 얻을 수 있으면 기뻐할 것입니다.

관련 문제