2013-04-16 3 views
1

C의 List 예제에서 새 노드가 스택의 끝까지 푸시됩니다. 새 노드를 끝까지 밀어 넣으려고하면 Bus Error: 10이 계속 나타납니다. 여기 내 푸시 기능입니다 :버스 오류 : C에서 구조체 포인터를 다루는 경우

void push(struct node *tail, struct node *newNode) { 

tail->next = newNode; // gdb says the problem is here 
tail = tail->next; 

} 

나는 또한 여기 내 구조체가 필요하다는 push(tail, newNode);

를 사용하여 전화 : 여기

struct node 
{ 
    int hour; 
    int minute; 
    char *name; 
    struct node *next; 
}; 

을 그리고 push()

로 이어지는 코드를 보여주는 주요 기능입니다
int main() 

{ 
char inputString[50]; 
int timeHour, timeMin; 
struct node *head; 
struct node *tail; 

while ((scanf("%d:%d", &timeHour, &timeMin)) != EOF) { 
    scanf("%s", inputString); 

    if (strcmp(inputString, "enqueue") == 0) { 
     if (head == NULL) { 
      head = malloc(sizeof(struct node)); 

      head->hour = timeHour; 
      head->minute = timeMin; 

      // get name 
      scanf("%s", inputString); 
      head->name = malloc(strlen(inputString)+1); 
      strcpy(head->name, inputString); 

      tail = head; 

      printEnqueue(head); 
     } else { 
      struct node *newEntry = malloc(sizeof(struct node)); 

      newEntry->hour = timeHour; 
      newEntry->minute = timeMin; 

      // get name 
      scanf("%s", inputString); 
      newEntry->name = malloc(strlen(inputString)+1); 
      strcpy(newEntry->name, inputString); 

      push(tail, newEntry); 

      printEnqueue(newEntry); 
     } 
    } else { 
     pop(&head, timeHour, timeMin); 
    } 
} 

return 0; 
} 
+1

왜 함수에 'newNode'에 대한 포인터에 대한 포인터를 전달하고 있습니까? 'newNode'에 대한 포인터를 수정하지 않으므로 포인터를 전달할 수 있습니다. 또한 디버거에서 포인터를 넘길 때 * newNode가 가리키는 포인터는 무엇입니까? 올바른 노드입니까? – user1118321

+0

'newNode'를 일반 포인터로 변경 한 후에 gdb에서'newNode = 0x100103920'을 가리키고 있습니다. 나는 그것이 유효한 노드인지 아닌지 확실하지 않기 때문에 메모리에 대해 많은 것을 모릅니다. – Slayter

+2

최소, ** compilable ** 테스트 케이스, 제발. 추측하지 않고이 질문에 대답하는 데 필요한 모든 정보가 없습니다. – Sebivor

답변

2

main 함수의 노드가 headtail 노드가 제대로 초기화되지 않은 것 같습니다.

코드에서 NULL 인 경우 head에 새 노드가 할당 된 것으로 보입니다. 그러나 head을 정의한다고해서 처음에 NULL이 아닌지 확인하지는 못합니다 (tail도 마찬가지). 따라서 if (head == NULL) 분기를 건너 뛸 수 있습니다 (실제로는 gdb에서 실행하십시오. :)).

Bus error은 거의 볼 수 없습니다. 그래서 나는 그것을 인터넷 검색 및 here에서, 버스 오류가 tail가 정렬 및 코드는 else 지점에 직접 실행되지 않기 때문에이있을 수 있습니다 때

using a processor instruction with an address that does not satisfy its alignment requirements.

발생할 수 있습니다. 따라서 push(tail, newEntry);은 정렬되지 않은 꼬리에 액세스합니다 (이 또한 나의 용의자의 유효성을 확인합니다). 당신이를 통과하지 않기 때문에 변경하지 않습니다 그것은 현재 '꼬리'가지고

+0

Annnnd that it! 감사. – Slayter

+1

@Slayter np. 다음번에, 정의 할 때 명시 적으로 초기화를 기억하십시오. : p –

+0

그래, 뭔가를 선언 할 때 기본적으로 'NULL'이라는 인상을 받았다. 하지만 그게 OOP 일이라고 생각해? – Slayter

1

수정 번호 3 : while ((scanf("%d:%d", &timeHour, &timeMin)) != EOF)이 루프 본문 내에서 timeHourtimeMin의 두 정수가 할당되었다고 보장 할 수 없습니다. 아마도 while ((scanf("%d:%d", &timeHour, &timeMin)) == 2)을 의미했을 것입니다.


개정 # 2 : 당신이 함수에 값을 전달하는 경우, 당신은 아닌 변수를 전달하고 있습니다. tailpush에 지정하면 발신자 (귀하의 main)에게 보이지 않습니다. 해당 변수에 대한 포인터 (예 : struct node **&head)를 전달하고 이전에 *tail에 할당해야합니다. 또는 push에서 return newNode;을 입력하고 반환 값을 새 head으로 사용하십시오.


개정 : 그것은 컴파일 것 같은이도 보이지 않는다. push을 살펴 보겠습니다.

void push(struct node **tail, struct node *newNode) { 
    (*tail)->next = *newNode; // gdb says the problem is here 
    *tail = (*tail)->next; 
} 

*newNode의 유형은 무엇입니까? struct node. (*tail)->next의 유형은 무엇입니까? 즉,이 코드에서의 :

struct node 
{ 
    int hour; 
    int minute; 
    char *name; 
    struct node *next; 
}; 

는 불일치를 수정하고 당신이 그것을 게시하기 전에 컴파일 가능한 당신의 최소한의 컴파일 가능한 테스트 케이스를 보장합니다.


scanf의 반환 값을 확인하는 것을 잊지 마세요! 귀하의 경우, 오류가 발생하지 않는 한 1을 리턴해야합니다. 당신이 '\0' 문자를 저장하기에 충분한 공간을 할당하지 않는 때문에


 head->name = malloc(strlen(inputString)); 
     strcpy(head->name, inputString); 

이것은 잘못된 것입니다. 나는 당신이 malloc(strlen(inputString) + 1)을 의미했다고 생각합니다. 코드에서이 오류의 두 인스턴스가 있습니다. 나 자신을 반복 할 계획이 아니야.


 struct node *newEntry = malloc(sizeof(struct node)); 
     push(&tail, newEntry); 

newEntry의 유형은 무엇입니까? struct node *.

 void push(struct node **tail, struct node **newNode) 

어떤 유형이 newNode입니까? struct node **. 불일치가 보이십니까? struct node **을 전달해야하지만 newEntrystruct node *입니다.

+0

죄송합니다. 'struct node * newNode'를 단일 포인터로 변경 한 후 내 질문을 변경하는 것을 잊어 버렸습니다. 또한 +1을'strlen (inputString)'에 추가 한 후에도 여전히 버스 오류가 발생합니다. – Slayter

+0

@Slayter 귀하의 편집 내용에 맞게 답변을 업데이트했습니다. – Sebivor

+0

@Slayter 질문을 다시 업데이트하려면 malloc 픽스를 추가하고 컴파일해야합니다. – Sebivor

1

변화

void push(struct node *tail, struct node *newNode) 
{ 
    tail->next = newNode; // gdb says the problem is here 
    tail = tail->next; 
} 

다음

void push(struct node **tail, struct node *newNode) 
{ 
    (*tail)->next = newNode; // gdb says the problem is here 
    (*tail) = (*tail)->next; 
} 

에하면이 대신

push(&tail, newEntry); 

과 같이 호출 변수의 주소를 함수에 지정하여 포인터가 가리키는 것을 변경할 수 없습니다.

또한 로컬 변수 (header, tail, ...)를 모두 초기화해야합니다. 은 버릇이이되도록하십시오.

+0

그건 원래 원래 있었던 것이지만 다른 누군가의 추천 때문에 바뀌 었습니다. 이것은 그것이되어야하는 방법이지만 실제 문제는 다른 곳에있었습니다. – Slayter

관련 문제