2010-01-06 2 views
0

두 번째 Pop() 호출에서 다음 코드가 충돌합니다. 저는 C로 초보자이며 한 시간 이상이 코드를 쳐다 보면서 오류를 볼 수 없습니다. 이 코드가 왜 충돌하는지에 대한 나를 도울 수있는 아이디어가 있습니까?스택에서 항목을 검색하는 동안 C 프로그램에서 충돌이 발생합니다.

#include <stdio.h> 

#define StackDataSize 100 

typedef struct Stack 
{ 
    int index; 
    void *data[StackDataSize]; 
} Stack; 

void* Pop(Stack *s) 
{ 
    if(s->index >= 0) 
    { 
     return s->data[s->index--]; 
    } 
    else 
    { 
     fprintf(stderr, "ERROR: Stack Empty\n"); 
     return NULL; 
    } 
} 

void Push(Stack *s, void *v) 
{ 
    if(s->index < StackDataSize) 
    { 
     s->data[++s->index] = v; 
    } 
    else 
    { 
     fprintf(stderr, "ERROR: Stack Full\n"); 
    } 
} 

int main(void) 
{ 
    Stack s = {-1}, *intstack = &s; 

    int x = 123456; 
    Push(intstack, &x); 

    printf("%d\n", *(int*)Pop(intstack)); 
    printf("%d\n", *(int*)Pop(intstack)); 

    return 0; 
} 
+1

디버거에서 밟았습니까? 각 행에서 멈추고 s를 확인하고 널 (null)을 나타냅니다. –

답변

11

두 번째 Pop에서는 스택이 비어 있고 스택이 비어 있으면 Pop이 NULL을 반환합니다. 그래서 두 번째 줄에

:

printf("%d\n", *(int*)Pop(intstack)); 

당신은 int에 대한 포인터로 NULL를 역 참조한다.

printf("%d\n", *(int*)NULL); 
0

"색인"회원이 서명했거나 서명하지 않았습니까? 부호가없는 경우 "s-> index--"표현식은 매우 큰 숫자가됩니다.

+0

검열을 통해 동의한다는 것은 동의 할 것입니다. –

1

빈 경우에 반환하는 NULL을 역 참조하려고합니다.

6

두 번째 팝이 빈 스택에서 팝하려고 시도하고 Pop() 함수가 NULL을 반환합니다. 그런 다음 주 함수는이 NULL 포인터를 역 참조하고 그 포인터가 가리키는 값을 인쇄합니다.

NULL 포인터가 유효하지 않은 항목을 가리 키므로 세그멘테이션 오류가 발생합니다.

3

당신이 다음 int *에 캐스팅 역 참조하려고 Pop 반환 NULL에 두 번째 호출. Dereferencing NULL은 segfault를 생성합니다.

2

이전 답변을 모두 표시하려면 Pop에 대한 두 번째 호출이 NULL을 반환하는 것이므로 printf()에 대한 두 번째 호출에서 역 참조하려고합니다.

void Push(Stack *s, void *v) 
{ 
    if (s->index) 
    s->data[--s->index] = v; 
    else 
    // overflow 
} 

void *Pop(Stack *s) 
{ 
    if (s->index < StackDataSize) 
    return s->data[s->index++]; 
    else 
    { 
    // underflow 
    return NULL; 
    } 
} 
... 
Stack s = {StackDataSize, {NULL}}; 

이 방법 0하지 않는 : 당신이 아니라 주위의 다른 방법보다는 위에서 아래로 성장하는 경우 어레이 기반 스택과 함께

순수하게 정보를 노트에

, 그것은 조금 쉽게 특별한 경우가된다. 난 당신의 코드를 보면 동안

0

, 나는 또한 충돌 원인이 다른 문제를 참조하십시오 난 당신이뿐만 아니라 Push()에 "해제 하나"오류가있어 생각, 여기 :

void Push(Stack *s, void *v) 
{ 
    if(s->index < StackDataSize) 
    { 
     s->data[++s->index] = v; 
    } 
    ... 

s->index < StackDataSize을 확인한 다음 사전 증분 ++s->index을 쓰고 s->data에 쓰면 s->index == StackDataSize - 1 인 경우 배열 끝에 1을 씁니다. 그러면 세분화 오류가 발생합니다.

관련 문제