2016-10-21 2 views
-1

링크 된 목록에서 모음을 삭제하는 중에 문제가 있습니다. 이 프로그램은 명령 줄 인수를 받아들이고이를 단일 문자열로 결합한 다음 각 문자를 노드로 연결된 목록에 추가합니다.링크 된 목록의 마지막 노드가 링크 된 경우 프로그램이 충돌합니다.

끝 문자가 모음이 아닌 명령 줄 인수로 프로그램을 실행하면 프로그램이 완벽하게 작동합니다. 그러나 인수가 모음으로 끝나면 프로그램은 Segmentation fault (코어 덤프) 메시지와 충돌합니다.이 문제를 어떻게 처리해야하는지 알지 못합니다 ..

프로그램에서 전역 변수를 만들면 안됩니다. stdio.h 문자열 이외의 다른 헤더 파일을 사용해서는 안됩니다. stdlib.h

모든 함수가 올바르게 작동합니다. locateVowels() 및 removeVowels()의 일부 실수로 인해이 문제가 발생할 수 있습니다. 기능하지만 나는 그 실수가 무엇인지 알 수 없다.

이 문제는 이중 포인터를 사용하여 해결할 수 있습니까 ?? 나는이 프로그램에서 무엇이 잘못되었는지 알 수 없다. 나는 C 프로그래밍에 익숙하지 않다. 제발 도와주세요. 제발 .. 제발 .. 미리 감사드립니다. 이 프로그램은 메뉴가 표시

#include<stdio.h> 
#include<string.h> 
#include<stdlib.h> 

struct linkedList { 
    char ch; 
    struct linkedList *node; 
}; 
void printMenu(void); 
char* combineWithNoSpaces(int, char *[]); 
void addTolinkedList(char *, struct linkedList **, int *); 
void printLinkedList(struct linkedList **); 
struct linkedList *locateVowel(struct linkedList *s); 
int delHead(struct linkedList **); 
void removeVowels(struct linkedList *); 
int isEmpty(struct linkedList **); 
int isVowel(char); 
void freeLinkedList(struct linkedList *); 

int main(int argc, char *argv[]) { 
    int choice, indexer = 0; 
    struct linkedList *s; 
    char *string; 
    if (argc == 1) { 
     printf("Parse a sentence"); 
    } else { 
     s = (struct linkedList *) malloc(sizeof(struct linkedList)); 
     string = combineWithNoSpaces(argc, argv); 
     addTolinkedList(string, &s, &indexer); 
     while (1) { 
      printMenu(); 
      scanf("%d", &choice); 
      if (choice == 1) { 
       printLinkedList(&s); 
      } else if (choice == 2) { 
       if (!delHead(&s)) 
        printf("Failed.Empty linked list"); 
      } else if (choice == 3) { 
       removeVowels(s); 

      } else if (choice == 4) { 
       if (isEmpty(&s)) { 
        printf("Empty LinkedList"); 
       } else 
        printf("Not Empty"); 
      } else if (choice == 5) { 
       freeLinkedList(s); 
       break; 
      } else 
       printf("Invalic choice"); 
      printf("\n"); 
     } 
    } 
    return 0; 
} 
int isVowel(char ch) { 
    return (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' 
      || ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U'); 
} 
void removeVowels(struct linkedList *s) { 

    s = locateVowel(s); 

    while (s != NULL) { 
     struct linkedList *temporary = s->node; 

     s->ch = temporary->ch; 
     s->node = temporary->node; 

     free(temporary); 

     s = locateVowel(s); 
    } 
} 
struct linkedList *locateVowel(struct linkedList *s) { 

    if (s == NULL) { 
     return s; 
    } 

    char ch = s->ch; 

    if (isVowel(ch)) { 
     return s; 
    } 

    if (s->node == NULL) { 
     return NULL; 
    } 

    return locateVowel(s->node); 
} 

int isEmpty(struct linkedList **s) { 
    if (*s == NULL) 
     return 1; 
    else 
     return 0; 
} 


int delHead(struct linkedList **s) { 
    struct linkedList *temp; 
    if ((*s) == NULL) { 
     return 0; 
    } else { 
     temp = (*s)->node; 
     free(*s); 
     *s = temp; 
     return 1; 
    } 
} 
void printLinkedList(struct linkedList **s) { 
    if ((*s) != NULL) { 
     printf("%c", (*s)->ch); 
     printLinkedList(&(*s)->node); 
    } 
    return; 
} 
void addTolinkedList(char *str, struct linkedList **s, int *indexer) { 
    if (*indexer == strlen(str)) { 
     *s = NULL; 
     return; 
    } else { 
     (*s)->ch = *(str + *indexer); 
     (*s)->node = (struct linkedList *) malloc(sizeof(struct linkedList)); 
     ++*indexer; 
     addTolinkedList(str, &(*s)->node, indexer); 
    } 
} 
char * combineWithNoSpaces(int argc, char *argv[]) { 
    int i, j; 
    int count = 0; 
    int memory = 0; 
    char *str; 
    for (i = 1; i < argc; i++) { 
     for (j = 0; j < strlen(argv[i]); j++) { 
      ++memory; 
     } 
    } 
    str = (char *) malloc(memory * sizeof(char) + 1); 
    for (i = 1; i < argc; i++) { 
     for (j = 0; j < strlen(argv[i]); j++) { 
      *(str + count) = argv[i][j]; 
      ++count; 
     } 
    } 
    *(str + memory + 1) = '\0'; 
    return str; 
} 
void freeLinkedList(struct linkedList *s) { 
    while (s != NULL) { 

     struct linkedList *temporary = s; 

     s = s->node; 

     free(temporary); 
    } 
} 
void printMenu(void) { 
    printf("\n\n" 
      "1. print input arguments (no spaces)\n" 
      "2. remove first character\n" 
      "3. remove vowels\n" 
      "4. is the linked list empty?\n" 
      "5. exit program\n" 
      "Enter your choice>"); 
} 

:

전체 코드는 아래와 같습니다. 정수 선택 항목 3은 removeVowels()를 실행하는 모음을 삭제하기위한 것이며 locateVowels()를 추가로 실행합니다. 출력을위한 스크린 샷은 다음과 같습니다 누구의 끝 문자
인수가 그 문자를 종료하는 것은 당신의 removeVolwel() 함수에서 모음 argument ending with vowel

+0

[디버거 사용 방법] (http://www.cprogramming.com/gdbtutorial.html)을 알아야합니다. –

+0

죄송합니다 .. 저는 무기력합니다 .. – user3213732

+0

아마도이 링크는 도움이 될 것입니다 : https://www.owasp.org/index.php/Using_freed_memory –

답변

1

, 같은 기능.
temporary->ch으로 NULL->ch이 세그먼트 오류로 발생합니다. 다음 코드의 수정 방법의

하나. (정책 덮어 쓰기보다는 노드를 제거 할 수 있습니다.)

void removeVowels(struct linkedList *s) { 
    s = locateVowel(s); 

    while (s != NULL) { 
     struct linkedList *temporary = s->node; 
     if(temporary == NULL){ 
      s->ch = '\0'; 
      s->node = NULL; 
      break; 
     } else { 
      s->ch = temporary->ch; 
      s->node = temporary->node; 
     } 

     free(temporary); 

     s = locateVowel(s); 
    } 
} 

void printLinkedList(struct linkedList **s) { 
    if ((*s) != NULL && (*s)->ch != '\0') { 
     printf("%c", (*s)->ch); 
     printLinkedList(&(*s)->node); 
    } 
    return; 
} 
0

당신이 temporary를 확인해야 NULL가 아닌 아닌 모음 argument with no ending vowel 인수입니다.

업데이트 s이 마지막 요소 인 경우 struct linkedList *temporary = s->node;
temporaryNULL 될 것 removeVowels에서

void removeVowels(struct linkedList *s) { 

    s = locateVowel(s); 

    while (s != NULL) { 
     struct linkedList *temporary = s->node; 
     /**********************/ 
     if (temporary == NULL) { 
      break 
     } 
     /******************/ 
     s->ch = temporary->ch; 
     s->node = temporary->node; 

     free(temporary); 

     s = locateVowel(s); 
    } 
} 
+0

마지막 요소에서 마지막 모음 요소를 제거하지 않습니다. – BLUEPIXY

+1

예, 정확하게 프로그램이 추락하지 않았습니다 ..하지만 마지막 모음 문자는 삭제되지 않았습니다 .. 선생님, 어떤 생각을 갖고 계시나요? – user3213732

+0

@ user3213732, 나는 충돌을 해결했습니다. 마지막 모음을 제거하지 않는 이유를 보려면 코드를 이해해야합니다. 그게 더 좋을지도 몰라! – Rohan

0

주의. 마지막 링크는 일반적으로 NULL을 가리키며 역 참조가 항상 NULL 체크가되지 않을 수도 있습니다!

+------+  +------+  +------+ 
| data |  | data |  | data | 
+------+  +------+  +------+ 
| next |---->| next |---->| next |----> NULL 
+------+  +------+  +------+ 
^
    | 
START (Keep track of the whole list.) 

희망을 명확히하는 데 도움이됩니다.