2010-03-21 3 views
2

C에서 대기열 데이터 구조를 링크 된 목록으로 지정해야합니다. 강사가 스택을 구현하기 위해 많은 양의 코드를 제공했지만 큐를 생성하려면 코드를 수정해야합니다. 강사가 우리에게 준 코드는 내가 큐에 쓴 코드와 정확히 같은 지점에서 컴파일 및 세그먼싱을하지 않습니다. 나는 구조체, malloc 및 C를 일반적으로 매우 새로 도입했기 때문에 간과 한 명백한 무언가가있을 수 있습니다. 여기 구조체와 동적 메모리 할당을 사용하는 큐

내가 사용하고있는 코드입니다 :

#include <stdio.h> 
#include <stdlib.h> 
struct node{ 
    int data;    //contains the actual data 
    struct node *prev;  //pointer to previous node (Closer to front) 
    struct node *next;  //pointer to next node (Closer to back) 
}; 

typedef struct node *Nodepointer; 

struct queue{ 
    Nodepointer front; 
    Nodepointer back; 
}; 

typedef struct queue *Queuepointer; 

main(){ 
    Queuepointer myqueue;  //create a queue called myqueue 
    init(myqueue);    //initialise the queue 
    Nodepointer new = (Nodepointer)malloc(sizeof(struct node)); 
    myqueue->front = new; 
} 

int init(Queuepointer q){ 
    q = (Queuepointer)malloc(sizeof(struct queue)); 
    q->front = NULL; 
    q->back = NULL; 
} 

아이디어는 큐 구조체는 큐에서 첫 번째와 마지막 노드를 '포함', 그리고 노드가 생성 될 때,이 MyQueue가 업데이트된다는 점이다. 그러나, 나는 심지어 그 부분에 도착할 수 없다 (팝과 푸시는 쓰여졌지만 간결함을 위해 생략되었다). 내가 무슨 일을하고 있어요

Program received signal SIGSEGV, Segmentation fault. 
0x08048401 in main() at queue.c:27 
27 myqueue->front = new; 

어떤 생각 : 코드 라인은 다음 GDB 출력

myqueue->front = new; 

에서 segfaulting입니까?

+0

단지 의견 : 키워드 'new'를 사용하지 마십시오. C++에 대한 예약어입니다. 나중에 C++ 프로그램에서 코드를 사용하는 경우 몇 가지 문제가 발생합니다. 그리고 malloc이 NULL이 아닌 값을 반환하는지 항상 확인하십시오 (좋은 습관). – Pierre

+0

용어에 대한 부가 설명 : 모든 노드에 전달 및 역방향 포인터가 모두 있기 때문에 여기에있는 것은 더 잘 * 이중 연결 * 목록이라고합니다. * 단일 링크 된 * 목록에서 모든 노드에는 전달 포인터 만 있습니다. * 연결된 목록 *을 말하면 어떤 종류인지에 대해 이야기하는 것이 좋습니다. – crazyscot

+0

Pierre, 고마워요 ... 저는 그것이 강사의 코드에 있다고 생각하지만, 어떤 이유로 그것을 생략했습니다. Crazyscot, 네가 맞아, 내 잘못이야. 고마워, 고마워. –

답변

5

당신이 초기화를 호출 할 때 :

int init(Queuepointer q){ 
    q = (Queuepointer)malloc(sizeof(struct queue)); 
    q->front = NULL; 
    q->back = NULL; 
} 

당신은 함수에 대기열에 대한 포인터를 전달 어디 초기화하고 함수 내 (메모리) 그 포인터를 가리 킵니다. q = ...을 설정하면 q에 새 값이 지정됩니다.

불행히도, 호출 함수는 이것을 보지 못합니다. 대신 포인터에 대한 포인터를 전달해야

int init(Queuepointer * qp){ 
    Queuepointer q = (Queuepointer)malloc(sizeof(struct queue)); 
    q->front = NULL; 
    q->back = NULL; 
    // Set qp: 
    *qp = q; 
} 

그런 다음 호출 기능을 변경 :

init(&myqueue); 
+0

대단히 감사합니다. 당신과 파벨의 대답은 모두 훌륭했습니다. 나는 코드를 훨씬 더 잘 이해한다고 생각한다. :) –

3

init (myqueue); 값에 의해 할당되지 않은 메모리에 대한 포인터를 전달합니다. init은 아무것도하지 않으므로 결과적으로 임의의 것들을 무작위로 작성합니다.

그런 다음 myqueue-> stuff가 다시 수행합니다.

포인터 포인터를 사용해야합니다.

초기화는 대기열 **을 받고 초기화 (& myqueue)라고합니다. 인사이드, * myqueue =() malloc stuff

또한이 typedef에 대해 추천합니다. 그들은 오히려 나쁜 스타일입니다.

2

내가 볼 첫 번째 문제는 "초기화"기능 "Q에 할당 된 포인터를 쓰는 것입니다 ", 그건 원래"myqueue "가 아닙니다. C는 인수를 값으로 전달한다는 것을 기억하십시오. 가능한 보정 (완전하지 단지 힌트)

Queuepointer init(void) 
    Queuepointer q; 
    q = (Queuepointer)malloc(sizeof(struct queue)); 
    q->front = NULL; 
    q->back = NULL; 
    return q; 
} 
` 

와 "메인"이다 :

이 MyQueue = 초기화();

또한 프로그램에서 malloc에 ​​의해 할당 된 요소를 초기화하지 않는다는 점에 유의하십시오. malloc은 일반적으로 메모리를 할당하지 않는다.

감사

0

당신은() 할당이 초기화에서 일어난 그래서 값이 MyQueue을 전달하는이 MyQueue 인하지 MyQueue 인의 사본입니다.

int init(Queuepointer* q){ 
    *q = (Queuepointer)malloc(sizeof(struct queue)); 
    *q->front = NULL; 
    *q->back = NULL; 
} 

당신은 주요

init(&myqueue); 
0
int init(Queuepointer q){ 
    q = (Queuepointer)malloc(sizeof(struct queue)); 
    q->front = NULL; 
    q->back = NULL; 
} 

마이너 nitpick에서 초기화()를 호출 할 수 있지만 init 함수 그래서 아마 변화에는 반환 값이 없습니다 :

그래서 올바른 버전입니다 그것을 위해 :

void init(Queuepointer *q) { 

또는

int init(Queuepointer * qp){ 
    Queuepointer q = (Queuepointer)malloc(sizeof(struct queue)); 
    q->front = NULL; 
    q->back = NULL; 
    *qp = q; 
    if(q) { 
     return 1; 
    } else return 0; 
} 

오류 검사를 수행하는 방법에 따라 조정하십시오.

관련 문제