2017-11-09 1 views
-1

두 개의 구조체를 만드는 데 문제가 있습니다. 하나는 가방이라고하고 다른 하나는 카드입니다. 이것은 내가 지금까지 가지고있는 것입니다 :(C++) 하나의 구조체가 다른 점을 가짐

struct Card 
{ 
    char suit; 
    int value; 

}; 

struct BagNode 
{ 
    Card* Card; 
    BagNode* next; 
}; 

void fillWithCards(BagNode *&head, BagNode *&tail, BagNode *&temp) 
{ 
char suits [] = {'s', 'h', 'd', 'c'}; 
int val [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; 

for (int x = 0; x < 4 ; x++) 
{ 
    for (int y =1 ; y <= 13 ; y++) 
    { 
     BagNode *now = new BagNode; 
     now -> Card -> suit = suits [x]; 
     now -> Card -> value = val [y]; 

     if (*&head == NULL && *&tail == NULL && *&temp == NULL) 
     {    
      head = now; 
      tail = now; 
      temp = now; 
     } 
     else if (*&tail != NULL && *&temp != NULL) 
     { 
      tail -> next = now; 
      temp -> next = now; 
      tail = now; 
      temp = now; 
     } 
     else 
     { 
      tail -> next = NULL; 
     } 
    } 
    } 
} 

문제는 내가 컴파일하고 프로그램을 실행할 때 충돌합니다. 문제가 관련되어 있다는 느낌이 들었습니다 Card* Card;

예, 카드에있는 모든 것을 가질 수 있다는 것을 알고 있습니다. 즉, *next이 있고 BagNode은 필요하지 않습니다. 그러나 교수에게 물어 보니 그는 Bag에 두 개의 구조체가 있고 Card에 두 개의 구조체가 있어야한다고했습니다.

이 문제를 도와주세요. 도움 주셔서 감사합니다.

+2

을이 [프로그램을 디버깅하는 방법]에 완벽한 시간 (https://ericlippert.com/2014/03/05/how-to-입니다 debug-small-programs /). –

+1

왜 가방 하나당 하나의 카드로 여러 가방의 연결 목록이 있습니까? 그 가방은 무엇을 나타낼 것인가? 여러 개의 카드가 들어있는 하나의 가방이 나에게 더 적합 할 것입니다. –

답변

2
BagNode *now = new BagNode; 

동적 범위에서 BagNode의 새 인스턴스를 생성합니다. 이 클래스에는 생성자가 없습니다. 이 클래스의 멤버 중 어느 것도 기본 생성자가 없습니다. 따라서이 클래스의 새 인스턴스는 완전히 초기화되지 않습니다. 직후 :

now -> Card -> suit = suits [x]; 
now -> Card -> value = val [y]; 

클래스의 새 인스턴스가 완전히 초기화되지 않은 때문에이가 시도의 정의되지 않은 동작, 초기화되지 않은 포인터 역 참조의 결과로 완전히 초기화되지 않은 Card 회원, 포인터, 그리고 명백한 충돌 역 참조.

표시된 코드에 다른 문제가있을 수 있지만 Minimum, Complete, and Verifiable Example이 제공되지 않았기 때문에 결론적으로 분석 할 수 없습니다. 할 수있는 유일한 다른 코멘트 :

if (*&head == NULL && *&tail == NULL && *&temp == NULL) 

*& 부분이 전혀 도움이 수행되지 않습니다. 이것은 논리적으로 다음과 같습니다 :

if (head == NULL && tail == NULL && temp == NULL) 

이 과정은 훨씬 더 읽기 쉽고 분명합니다.

1

당신은 operator->으로 Card* 포인터를 역 참조하기 전에 유효한 Card 예를 가리 키도록 now->Card 초기화되지 않습니다. now->Card은 초기화되지 않은 포인터이므로 Card->이 잘못된 메모리에 액세스하고 있습니다.

또한 now->next도 초기화하지 않습니다. 리스트에 아직 삽입되지 않은 새로운 노드의 경우 노드가 아직 뒤 따르지 않으므로 NULL로 초기화되어야합니다.

나는 Card card;Card* Card;를 변경 제안하고 Card 필드에 액세스 할 수 operator-> 대신 operator.을 사용 : 그렇게 말

struct BagNode 
{ 
    Card card; // <-- no '*' ! 
    BagNode* next; 
}; 

... 

BagNode *now = new BagNode; 
now->Card.suit = suits [x]; 
now->Card.value = val [y]; 
now->next = NULL; // <-- don't forget this! 

이제, 코드의 나머지 부분은 이해가되지 않습니다. 좋은 연결 목록 삽입이 아니며 temp 매개 변수를 사용하면 더 혼란 스럽습니다. temp은 무엇을 나타낼 예정입니까? head/tail이 NULL이지만 temp이 NULL이 아니면 코드가 충돌합니다. temp은이 종류의 코드에 속하지 않습니다.

또한 val[] 배열 범위를 벗어납니다. 배열은 0 인덱싱되지 않고 1 인덱싱되지 않습니다. val[]에는 13 개의 요소가 있으므로 유효한 색인은 1-13이 아닌 0-12입니다.

대신 이와 비슷한 더 많은 것을보십시오 :

struct Card 
{ 
    char suit; 
    int value; 
}; 

struct Bag 
{ 
    Card card; 
    Bag* next; 
}; 

void fillWithCards(Bag* &head, Bag* &tail) 
{ 
    const char suits[] = {'s', 'h', 'd', 'c'}; 
    const int val[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; 

    for (int x = 0; x < 4 ; x++) 
    { 
     for (int y = 0; y < 13; y++) 
     { 
      Bag *b = new Bag; 
      b->card.suit = suits[x]; 
      b->card.value = val[y]; 
      b->next = NULL; 

      if (!head) 
       head = b; 

      if (tail) 
       tail->next = b; 
      tail = b; 
     } 
    } 
} 
관련 문제