2016-09-12 4 views
1

사용자로부터 입력 문자열을 가져온 다음 문자열의 문자를 사용하여 이중 연결된 목록을 채워야하는 할당이 있습니다. 즉, 사용자 문자열을 반복하고 이중 연결 목록을 생성해야합니다. for 루프를 만들었고 출력이 작동하지만 출력을 표시 한 직후 프로그램이 중단됩니다. 나는 C++에서 총 2 주간의 경험을 가지고 있으므로 신기한 실수를 용서해주십시오. 아래 코드를 찾으십시오.C++ For 루프를 사용하여 이중 연결 목록

#include<cstdlib> 
#include<iostream> 
#include <string> 

using namespace std; 

struct node { 
    string data; 
    node *next; 
    node *prev; 
}; 

string getString() { 
    string userString; 
    cout << " Please enter a string for reversal: "; 
    cin >> userString; 
    return userString; 
} 

// print forward 
void printDataFor(node* head); 
// print reverse 
void printDataRev(node* tail); 

int main() { 
    node* head= new node; 
    node* tail= new node; 
    node* n; 
    string reverse = getString(); 
    int length = reverse.length(); 

    // loop to create linked list 
    for (int i = 0; i < length - 1; i++) { 
     if (head->prev == NULL) { 
      n = new node; 
      n->data = reverse[i]; 
      n->prev = NULL; 
      head = n; 
      tail = n; 
     } 
     else { 
      n = new node; 
      n->data = reverse[i]; 
      n->prev = tail; 
      tail->next = n; 
      tail = n; 
     } 
    } 

    n = new node; 
    n->data = reverse[length-1]; 
    n->prev = tail; 
    tail->next = n; 
    tail = n; 
    tail->next = NULL; 
    // call to print reverse 
    printDataRev(tail); 
} 

// print forward 
void printDataFor(node* head) { 
    node* temp = head; 
    while (temp != NULL) { 
     cout << temp->data; 
     temp = temp->next; 
    } 
} 

// print reverse 
void printDataRev(node* tail) { 
    node* temp = tail; 
    while (temp != NULL) { 
     cout << temp->data; 
     temp = temp->prev; 
    } 
} 

답변

0

표시된 코드에 여러 가지 버그가 있습니다. 새롭게 구축되는 노드가 NULL로 초기화 prevnext 포인터있을 것이라는 점을

node* head= new node; 

// ... 

if (head->prev == NULL) { 

당신은 기대하고 있습니다.

이것은 매우 합리적입니다. new 아무것도에 nextprev를 초기화하지 않을, 명시 적 생성자없이

struct node { 
    string data; 
    node *next; 
    node *prev; 
}; 

: 문제는 그렇게 할 것입니다 코드에서 아무 것도 없다는 것이다. 그들은 쓰레기가 될 것이고, 표시된 코드는 어떤 시점에서 쓰레기 포인터를 derefence하려고 시도 할 것이고, 충돌을 일으킬 것입니다.

NULL로 초기화하거나 (현재 C++ 표준에 도입 된 새로운 구문을 사용하고 두 가지 모두에 대해 기본 이니셜 라이저를 선언하려면) 명시 적 생성자가 필요합니다.

이것은 첫 번째 문제입니다.

두 번째 문제는 주 for 루프가 일부 이유가 없기 때문에 필요한 횟수보다 적은 횟수만큼 반복되도록 코딩되어 있으며 마지막 값을 연결된 목록에 삽입하는 중복 된 코드 조각이 있다는 것입니다. 이것이 필요한 이유가 전혀 없습니다. 모든 문자를 반복하여 삽입하십시오.

세 번째 문제는 로직이 여분의 headtail 노드를 연결 목록에 삽입하여 데이터가 빈 문자열로 나타나는 것입니다. 링크 된 목록을 인쇄하는 루프는 단순히 빈 문자열을 출력하기 때문에 보이는 것에서 보이는 효과는 보이지 않습니다. 여전히 기술적으로 잘못된 것입니다.

복제 된 가짜 노드를 제거하려면 논리를 조정해야합니다. 대신 new의, NULLheadtail를 초기화하여 시작, 대부분 쓸모없는, 노드 :

node *head=NULL; 
node *tail=NULL; 

는 그런 다음에 대한 루프 따라의 논리를 조정 문자열의 첫 번째 문자의 가장자리 조건을 테스트하기 이 노드는 headtail을 가리키는 새 노드를 만들고 head 앞에 각 후속 문자를 삽입하는 일반 실행 경로를 만듭니다.

+0

또 다른 문제는 'head-> prev == NULL'이 초기화 루프에서 항상 true라는 것입니다. –