2016-10-21 2 views
-1

У меня возникла проблема при удалении гласного из связанного списка. Программа принимает аргументы командной строки, объединяет их в одну строку и добавляет каждый символ в связанный список как узел.Программа вылетает, если связанный последний узел связанного списка удален

, когда программа выполняется с аргументом командной строки, символ окончания которой не является гласным, программа работает отлично. Но когда аргумент заканчивается гласным, программа выходит из строя с сообщением о сбое сегментации (ядро сбрасывается). Я не понимаю, как с этим справиться.

Программа не должна создавать глобальные переменные, поэтому i ' ve использовал двойной указатель. Программа не должна использовать другие файлы заголовков, чем stdio.h string.h stdlib.h

Все функции работают исправно, эта проблема может возникнуть из-за некоторых ошибок в locateVowels() и removeVowels() но я не могу понять, что это за ошибка.

можно решить эту проблему, используя двойной указатель ?? Я не могу понять, что не так в этой программе. Я новичок в программировании, пожалуйста, помогите мне с этим .. Пожалуйста, исправьте меня .. Заранее спасибо.

Полный код приведен ниже:

#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(). снимок экрана для вывода является:
аргумент, чей конечный символ не гласный argument with no ending vowel аргумент которого заканчивается характер гласный argument ending with vowel

+0

Вы должны узнать [как использовать отладчик] (http://www.cprogramming.com/gdbtutorial.html). –

+0

извините, сэр .. я беспомощный .. – user3213732

+0

Возможно, эта ссылка поможет: https://www.owasp.org/index.php/Using_freed_memory –

ответ

1

в removeVowels, struct linkedList *temporary = s->node;
temporary будет NULL, когда s является последним элементом.
Таким образом, temporary->ch как NULL->ch возникает ошибка сегментации.

Одним из пути исправления, в следующем коде. (Policy перезаписать вместо того, чтобы удалить узел.)

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

В вашей removeVolwel() функции вам нужно проверить temporary не NULL.

Обновление функционируют как

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.) 

Надежды, которые помогают уточнить.

Смежные вопросы