2013-03-17 2 views
0

필자는 라이브러리를 만들고 있는데, 포인터 구문을 이해한다고 생각했을 때 혼란스러워지고 웹 검색을 통해 더욱 혼란스러워집니다. contextC로 포인터로 풀을 만들려면 어떻게해야합니까?

다음 사항

존중해야합니다 :

는 기본적으로 나는 풀을 만들고 싶어, 여기에 내가 실제로하고 싶은 것입니다

  • 나는 객체를 추가 할 때 풀에 객체에 대한 현재 배열의 포인터는 (새 객체를 포함하기 위해) 새 포인터 배열 +1에 추가됩니다.
  • 새 배열은 내 foo 구조의 "objects"로 지정됩니다.
  • 이전 어레이는 무료입니다. 내가 정리 함수를 호출 할 때
  • 는 풀의 모든 객체는 는

가 어떻게 내 구조를 정의한다를 free되기를입니까? 객체의 유형을 사전에 알 수없는 풀에 추가, 그래서 내가해야 무효가 모든 포인터를 처리합니다

void myc_pool_init() 
{ 
    the_pool = (???)malloc(sizeof(???)); 
    the_pool->n = 0; 
    the_pool->objects = NULL; 
} 

void myc_push_in_pool (void* object) 
{ 
    if (object != NULL) { 
     int i; 
     (???)new_pointers; 

     the_pool->n++; 
     new_pointers = (???)malloc(sizeof(???)*the_pool->n); 

     for (i = 0; i < the_pool->n - 1; ++i) { 
      new_pointers[i] = (the_pool->objects)[i]; // that doesn't work (as I'm not sure how to handle it) 
     } 
     new_array[i] = object; 

     free(the_pool->objects); 
     the_pool->objects = new_array; // that must be wrong 
    } 
} 

void myc_pool_cleanup() 
{ 
    int i; 
    for (i = 0; i < the_pool->n; ++i) 
     free((the_pool->objects)[i]); // as in myc_push_in_pool, it doesn't work 
    free(the_pool->objects); 
    free(the_pool); 
} 

참고 : 여기

typedef struct { 
    int n; 
    (???)objects 
} foo; 
foo *the_pool; 

내 수영장을 관리하는 코드이다 모든 의견은 매우 환영받을 것입니다.

+0

C가 이런 유형의 제네릭 프로그래밍을 사용했다면 [qsort] (http://pubs.opengroup.org/onlinepubs/009695399/functions/qsort.html)가 콜백 함수 대신 width 인수? – Sebivor

+0

@GrijeshChauhan이 책은 첫 번째 페이지에서 "객체 지향 만이 프로젝트 간 코드 재사용을 허용합니다"라고 말합니다. 말도 안되는 소리! 이 저자는 매우 혼란 스럽습니다. 객체 지향없이 코드 재사용이 불가능한 경우 하스켈에서 추상화를 설명하십시오. – Sebivor

+1

Ted Jensen의 "C의 배열과 포인터에 관한 튜토리얼"(http://home.earthlink.net/~momotuk/pointers.pdf)을 살펴보고 Steve Summit의 [ "Introductory C programming" (http://www.eskimo.com/~scs/cclass/cclass.html). 날짜가 있지만 어쨌든 여기에 묻기 전에 반드시 읽어야합니다. – vonbrand

답변

3

질문에 대한 대답은 void *입니다. 이 유형은 풀에 모든 종류의 포인터를 넣을 수 있으므로 매우 강력합니다. 그러나 풀에서 void * 포인터를 검색 할 때 올바른 캐스트를 수행하는 것은 사용자의 몫입니다.

귀하의 구조체로서이

typedef struct { 
    int n; 
    (void **)objects 
} foo; 
foo *the_pool; 

처럼 포인터의 배열을 보일 것이다.

귀하의 malloc :

new_pointers = (void **)malloc(sizeof(void *)*the_pool->n); 

가 여기에 성능 문제가 있습니다. 단순히 고정 된 크기의 배열을 할당하고 요소 수가 미리 정의 된로드 요소 (= 사용 된 숫자/최대 크기)를 초과하는 경우에만 다시 할당 할 수 있습니다.

또한 포인터를 추가 할 때마다 새 포인터를 할당하는 대신 풀은, 당신은 모든 것을 복사 할 필요없이, realloc (http://www.cplusplus.com/reference/cstdlib/realloc/)

the_pool->objects = (void **)realloc(the_pool->objects, the_pool->n* sizeof(void*)); 

realloc 함수는 현재 할당 된 면적을 증가하려고 사용할 수 있습니다. 함수가 할당 된 영역을 연속적으로 증가시킬 수없는 경우에만 새로운 영역을 할당하고 모든 것을 복사합니다.

+4

malloc에서 반환 값을 캐스팅 할 필요가 없습니다. –

+0

정말이 답변을 주셔서 감사합니다. 이제 포인터 사용을 이해합니다. realloc 팁 주셔서 감사합니다. – user544262772

0

먼저 "이미 foo.objects의 유형은 무엇입니까?"질문 : void *objects;는 malloc에 ​​이미 void *을 반환 귀하의 구조체는 역시 size_t item_size; 저장해야 n는 아마도 있어야 할 size_t 집에서 성장 루프를 사용하지만, 수

typedef struct { 
    size_t item_count; 
    size_t item_size; 
    void *objects; 
} foo; 
foo *the_pool; 

당신은 나는 것입니다... 방어 적이기이 새로운 공간으로 이전 항목을 복사 할 수있는보다 편리한 방법이라고 생각하고에 새 항목이 새로운 공간입니다.

void *를 역 참조 제약 조건 위반이, 그래서, new_pointersvoid *에 포인터 연산 같이 것이다 필요한 것 다른 유형이어야합니다. 올바른 크기의 객체를 가리키는 유형이 필요합니다. 당신과 같이, unsigned char의 오른쪽 숫자의 배열을 사용할 수 있습니다

// new_pointers is a pointer to array of the_pool->item_size unsigned chars. 
unsigned char (*new_pointers)[the_pool->item_size] = malloc(the_pool->item_count * sizeof *new_pointers); 

// copy the old items 
memcpy(new_pointers, the_pool->objects, the_pool->item_count * sizeof *new_pointers); 

// copy the new items 
memcpy(new_pointers + the_pool->item_count, object, sizeof *new_pointers); 

, 무료 ()를의 malloc (에 의해 반환 된 포인터 만)이며, 하나의 투가 있어야 기억 하나의 서신 : 각 malloc()은 free()이어야합니다. d. 당신이 어떻게 malloc을 보았습니까? new_pointers = malloc(sizeof(???)*the_pool->n); ... 당신이 루프를 (myc_pool_cleanup에서) 루프가 필요하다고 생각하게 만들면 각 아이템을 무료로 사용할 수 있습니다.

은 realloc을 사용할 수 있지만 그렇지 않으면 myc_push_in_pool *에서 malloc/memcpy/free *를 완벽하게 처리하는 것처럼 보입니다. 많은 사람들이 realloc 코드를 작성할 때 엉망이되는 경향이 있습니다.

관련 문제