2013-11-25 6 views
0

내 pop() 함수에 문제가 있습니다. 내 프로그램을 실행할 때 pop() 함수를 처음 호출 할 때 항목을 아무 문제없이 반환하지만, 시도 할 때 두 번째 항목을 연속해서 팝하면 실패합니다. 나는 이유를 알 수없는 것 같은데, 내 기능에서 빠진 것이 있는가?PHP pop() 함수와 관련된 문제

#define DEFAULT_CAPACITY 16 

struct stack { 
    size_t capacity; 
    size_t size; 
    stack_item *data; 
}; 

stack *new_stack (void) { 
    stack *this = malloc (sizeof (stack)); 
    assert (this != NULL); 
    this->capacity = DEFAULT_CAPACITY; 
    this->size = 0; 
    this->data = calloc (this->capacity, sizeof (stack_item)); 
    assert (this->data != NULL); 
    return this; 
} 

void free_stack (stack *this) { 
    assert (empty_stack (this)); 
    free (this->data); 
    free (this); 
} 

static bool full_stack (stack *this) { 
    return this->size == this->capacity; 
} 

static void realloc_stack (stack *this) { 
    size_t old_capacity = this->capacity; 
    this->capacity *= 2; 
    this->data = realloc (this->data, this->capacity); 
    memset (this->data + old_capacity, 0, old_capacity); 
    assert (this->data != NULL); 
} 


void push_stack (stack *this, stack_item item) { 
    if (full_stack (this)) realloc_stack (this); 
    //increase size of stack 
    this->data[this->size] = item; 
    this->size++; 
} 

stack_item pop_stack (stack *this) { 
    assert (! empty_stack (this)); 
    printf("Stack size: %lu\n", this->size); 
    return this->data[this->size--]; 
} 
+0

어떻게 실패합니까? 출력을 추가 할 수 있습니까? 'stack_item'은 무엇입니까? –

+0

크기의 범위를 확인해야합니다. 더 많은 코드를 제공하십시오. – moeCake

+0

어설 션에서 실패했을 수 있습니다. 즉, empty_stack 함수가 잘못되었을 수 있습니다 (false를 반환). 고려해야 할 다른 점은 stack_item * 데이터가 올바르게 구성되지 않았을 수 있습니다. 오류를 게시하고 스택이 채워지고 검사되는 방법을 게시하십시오. –

답변

2

"실패"의 의미에 따라 다릅니다. 데이터를 밀어

  • 코드가 잘못되어

    는 (완전한 의미없이) 등이 실패 할 수 많은 이유가 있습니다.

  • 용량이 충분하지 않습니다.
  • 팝업 할 항목이 충분하지 않습니다 (스택 언더 플로).

의 라인을 따라 디버깅을위한 dump_stack 함수를 작성하면된다해야하는 일 :

void dump_stack (char *desc, stack *this) { 
    printf ("%s: size/capacity: %lu/%lu\n", 
     desc, this->size, this->capacity); 
    for (size_t idx = 0; idx < this->size; idx++) { 
     // print out this->data[idx], depends on data type 
    } 
} 

문제가 자리하고있는 곳 당신이 그것을 호출하는 경우이 크게 파악에 도움이 될 것입니다 각각의 스택 작업 (push, pop, peek, clear, dup, rot, 2dup, 3rot 등) 후에.


이제 코드를 추가 했으므로 살펴볼 항목이 있습니다.

먼저 stack_item 유형입니다. 정확히 char과 같은 크기가 아니라면 메모리 할당 기능이 올바르지 않습니다. 예를 들어 4 바이트 정수이면 현재 메모리의 4 배를 할당해야합니다. 할당량에 sizeof(stack_item)을 곱하면이 문제를 해결할 수 있습니다.

전화 번호는 calloc이며 (그 크기를 입력해야하므로) realloc 전화 번호는 사용하지 않았습니다.


둘째, 당신의 realloc_stack 기능, 당신은 정말 memsetassert 일을해야하기 전에. 어떤 이유로 재 할당이 실패한 경우 을 메모리에으로 지정하는 것은 좋지 않습니다. 또는 런타임에 발생하지 않을 수있는 오류를 잡아 assert에 의존


셋째, 나쁜 생각이다. assert은 일반적으로 비 디버그 코드 (NDEBUG 기반)에 아무 것도 넣지 않으므로 메모리가 부족하면 잡을 수 없기 때문입니다. exit() (예를 들어)과 함께 자신의 오류 처리 기능을 제공해야 할 수도 있습니다.

나는 문제가있는 경우 러그를 밖으로 꺼내는 라이브러리 유형 코드에 대한 열렬한 팬이 아닙니다. 항상 발신자에게 표시를 반환하도록하는 것이 더 좋습니다. 무엇을 결정할 것인가? 그게 바로 메모리가 부족할 때을 생산 코드에서 사용하지 않는 이유입니다.스택 끝이 size 기반으로 어디에 코드를 알고 있기 때문에


넷째, 여기 callocmemset를 사용하는 것은 거의 확실 낭비이다. size 위의 항목과 capacity 아래의 항목이 0으로 설정되어 있는지 또는 푸시 작업으로 처음 설정하지 않고 사용하지 않으므로 임의의 값은 부적합합니다.

+2

인공 지능 로봇에 대한 꽤 좋은 일반화 :) –

+0

도움과 방향에 감사드립니다, 그것은 매우 감사하겠습니다. – marcello

관련 문제