2013-02-11 2 views
1

C에서 스택을 구현하려고하지만 새로운 데이터가 추가 될 때마다 이전 값이 대체됩니다. 여기 내 코드는 다음과 같습니다.C 스택 구현의 값 변경

#include <stdlib.h> 

struct snode { 
    int data; 
    struct snode *prev; 
    struct snode *next; 
}; 

static struct snode stack; 
static struct snode *stackpointer = NULL; 

void push(int data) { 
    if(stackpointer == NULL) { 
     stack.data = data; 
     stack.prev = NULL; 
     stack.next = NULL; 
     stackpointer = &stack; 
     return; 
    } 

    struct snode newnode; 
    newnode.data = data; 
    newnode.prev = stackpointer; 
    newnode.next = NULL; 
    stackpointer = &newnode; 
} 

int pop() { 
    int retdata = stackpointer->data; 
    if(stackpointer->prev == NULL) { 
     stackpointer = NULL; 
    } 
    else { 
     stackpointer = stackpointer->prev; 
     stackpointer->next = NULL; 
    } 
    return retdata; 
} 

int peek() { 
    return stackpointer->data; 
} 

push에서 새 노드가 선언 될 때마다 데이터는 스택의 모든 이전 값에서 변경됩니다. 뭔가 무작위로 값을 변경하게하는 포인터에 대해 알지 못하는 무언가가 있습니까?

EDIT :이 새로운 코드 동작 :

#include <stdlib.h> 

struct snode { 
    int data; 
    struct snode *prev; 
    struct snode *next; 
}; 

static struct snode *stackpointer = NULL; 

void push(int data) { 
    struct snode *newnode = (struct snode*)malloc(sizeof(struct snode)); 
    newnode->data = data; 
    newnode->prev = stackpointer; 
    newnode->next = NULL; 
    stackpointer = newnode; 
} 

int pop() { 
    int retdata = stackpointer->data; 
    if(stackpointer->prev != NULL) { 
     stackpointer = stackpointer->prev; 
     free(stackpointer->next); 
    } 
    else { 
     free(stackpointer); 
     stackpointer = NULL; 
    } 

    return retdata; 
} 

int peek() { 
    return stackpointer->data; 
} 

답변

4

stackpointer는 로컬 변수의 어드레스가 할당되고 push() 함수이다. 함수가 stackpointer을 반환하면 매달린 포인터가되고 newnode은 더 이상 유효하지 않습니다. 동적 malloc()를 사용하여 스택에 대한 새로운 노드를 할당 :

struct snode* newnode = malloc(sizeof(*newnode)); 

stackpointerstack의 주소에 할당되고 push()에 첫 번째 호출에서와 스택의 요소의 저장을 혼합하지 마십시오. 스택을 올바르게 구현하려면 노드를 동적으로 할당해야합니다. free()도 필요합니다. stack의 주소를 free()으로 전달하는 것은 잘못되었습니다. 스택의 사용을 일관되게 유지하면 복잡성을 피할 수 있습니다. 항상 동적으로 노드를 할당하고 항상 노드를 비우십시오.

+0

코드에 누락 된 'sizeof'을 추가했습니다. – unwind

+0

@unwind, thanks. – hmjd

+0

Ahh, 고마워요. 전에 이것을 한 번 보았지만, 이제 알게되었습니다. – mrobinson7627

0

malloc을 사용하여 새 노드를 할당해야합니다. 그냥 push 안에 만들어 두었고 다음 번에 push (또는 다른 루틴)이 호출 될 때 clobbered가됩니다.

그런데 next 포인터는 필요하지 않으며 prev뿐입니다.

1

푸시 할 때마다 매번 새 노드를 만들어야합니다.

변경이 :

struct snode newnode; 

에 :

struct snode *newnode = malloc(sizeof(struct snode)); 

다음 newnode->newnode.을 변경합니다. 그런 일이, 그것은 심하게 덮어 결코 극복, 또는 귀하의 질문에 "내가 왜 pop()을 이상하게 내 프로그램 충돌 호출 않을 때이 될 것입니다 그리고만큼 push - 약자로

는 변수 newnode 만 기능 push 내부에 존재한다. 코드에서 같은 함수에서 호출되면 스택에 같은 위치가 사용되므로 스택에 다른 항목을 추가 할 때마다 동일한 항목 (곧 "사용되지 않는"위치)에 보관 된 이전 값을 덮어 씁니다. 스택에