2010-05-26 4 views
2

저는 재미있는 배열 구조를 개발 중입니다. 템플릿 매개 변수로 일반화 된이 구조는 시작시 주어진 수의 항목을 미리 할당 한 다음 "사용 중"항목이 사용 가능한 항목보다 많으면 함수가 내부 버퍼를 다시 할당합니다. 테스팅 코드는 다음과 같습니다이상한 realloc 동작

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

template <typename T> struct darray_t { 
    size_t items; 
    size_t busy; 
    T  *data; 
}; 

#define DARRAY_REALLOC_ITEMS_STEP 10 

#define da_size(da) (da)->busy 

template <typename T> 
void da_init(darray_t<T> *da, size_t prealloc){ 
    da->items = prealloc; 
    da->busy = 0; 
    da->data = (T *)malloc(sizeof(T) * prealloc); 
} 

template <typename T> T *da_next(darray_t<T> *da){ 
    if(da->busy >= da->items){ 
     da->data = (T *)realloc(da->data, sizeof(T) * DARRAY_REALLOC_ITEMS_STEP); 
     da->items += DARRAY_REALLOC_ITEMS_STEP; 
    } 
    return &da->data[ da->busy++ ]; 
} 

int main(){ 
    darray_t<int> vi; 
    int *n; 

    da_init(&vi, 100); 

    for(int i = 0; i < 101; ++i){ 
     n = da_next(&vi); 
     *n = i; 
    } 

    for(int i = 0; i < da_size(&vi); ++i){ 
     if(vi.data[i] != i){ 
      printf("!!! %d != %d\n", i, vi.data[i]); 
     } 
    } 

    return 0; 
} 

당신이 볼 수 있듯이, 나는 처음에 100 정수 포인터를 prealloc 후 나는 한 번에 10 개의 포인터를 realloc 함수. 주 함수에서 for 루프를 수행하여 항목의 무결성을 검사합니다. 배열 항목이 예상과 다를 경우 해당 값을 인쇄하고 ... 알겠 니? 다음 메시지가 나타납니다.

!!! 11! = 135121

사실 인덱스 11의 항목은 '11'이어야합니다. 135121 !!!! : S

내 코드가 올바르지 않다는 것을 말해 줄 수 있습니까?

덕분에 내가 완벽하게 C와 C를 믹싱 ++이 방법은 추한 것을 알고, 내가 사용하는 경우,이 구조는 예를 들어, 망치 것이라고도 알고

참고 :

darray_t<std::string> 

이것은 int 포인터에 대한 테스트 일뿐입니다.

+1

윽, 템플릿 C, 어떤 추한 혼합. (템플릿을'std :: string'으로 인스턴스화하면 어떻게 될 것이라고 생각하십니까?) – sbi

+0

아시다시피, 그냥 테스트입니다! :) –

+0

이 구조체는 클래스와 함께 사용하기위한 것이 아니며, 분명히 그 경우에는 new 연산자를 사용하여 alloc (클래스 ctor를 호출)해야하며 realloc을 사용할 수 없습니다. 하지만 반복합니다. 이것은 int 포인터에 대한 테스트 일뿐입니다. –

답변

3

realloc이 자동으로 메모리 조각을 늘리지는 않습니다 - 그렇게해야 할 것입니다. : 예컨대

da->data=(T*)realloc(da->data, sizeof(T)*(da->items+DARRAY_REALLOC_ITEMS_STEP)); 

를 수행합니다 (당신은 NULL을 반환 realloc을 처리해야)

1

블록의 크기는 올바르지 않습니다

da->data = (T *)realloc(da->data, sizeof(T) * DARRAY_REALLOC_ITEMS_STEP); 

전체 블록이 증가만큼 큽니다. 시도해보십시오.

da->busy + sizeof(T) * DARRAY_REALLOC_ITEMS_STEP