1

私はクラスで Java から C の学習に移行しています。現在の課題は、LinkedList の removeAtFront()、searchNode()、および freeList() メソッドを実装することです。私はこれがどのように機能するかを理論的に理解しています.Javaですばやく実行したいのですが、何時間も試してみましたが、以下のコードが機能しない理由がわかりません.

ノードを削除した後に search メソッドが呼び出されるまで、remove メソッドは機能しているように見え、正しい変更済みリストを生成します。すると、必ずセグフォルト11が発生する。無料の方法でも、常にセグ フォールトが発生します。

私は宿題をするように人々に求めているわけではありませんが、正しい方向に向けることができれば、それは大歓迎です!

指定された Node* 構造体は次のとおりです。

typedef struct Node
{
  char  *word;
  struct Node  *next;
} Node;

main() の外側のメソッドは次のようになります。

void insertAtFront( Node **head, char * key )
{
    Node *new =  malloc( sizeof(Node) );
    if (!new)  fatal("Malloc of new Node failed");
    new->word = key;
    new->next = *head;
    *head = new;
}

void insertAtTail( Node **head, char * word )
{
    if (!(*head)) insertAtFront(head, word);    
    else insertAtTail(&(*head)->next, word);
}

void removeAtFront( Node ** head )
{
    Node *tmp = *head;
    if (!tmp) return;

    *head = tmp->next;
    free(tmp->word);
    free (tmp); 
}

void removeNode( Node ** head, char * key )
{
    Node *tmp = searchNode(*head, key);
    if (tmp) removeAtFront (&tmp);
}

Node * searchNode ( Node * head, char * key )
{   
    if (!head || (strcmp(head->word, key) == 0)) return head;
    return searchNode(head->next, key);
}

void freeList(  Node ** head )
{
    if (!head) return;
if (&(*head)->next) freeList (&(*head)->next);
    removeAtFront(head);
}

編集:コメントの 1 つが freeList() メソッドに関する私の問題を解決しましたが、他の人はより多くのコードを要求しました。この割り当ての問題は、insertAtTail()、removeAtFront()、remove()、search()、および freeList() メソッドのみを変更できることです。ただし、主な方法を以下に投稿します。ただし、単語の値はその中で正しく割り当てられていると思います。

Node *searchNode( Node * head, char * key );
void insertAtFront( Node **head, char * key );  // ALREADY WRITTEN FOR YOU 
void insertAtTail( Node **head, char * key );
void removeAtFront( Node ** head );
void removeNode( Node **head, char * key );
void freeList( Node **head );
void printList( Node * head ); // ALREADY WRITTEN FOR YOU
void fatal( char * msg ); // ALREADY WRITTEN FOR YOU

#define BUFFER_CAP 20

int main() 
{
  Node *head = NULL;

  while (1)
  {
    char option;
    printf("\nChoose 'H'ead Insert, 'T'ail insert, 'R'emove, 'S'earch, F'ree,     'Q'uit " );
    fflush( stdout );
    int result = scanf(" %c%*[^\n]", &option); getchar();  // MAGIC BULLET TO CORRECTLY READ A SINGLE CHAR FROM STDIN
    if (result <1) fatal("failure reading from stdin\n");

    if (option == 'H' )
    {
        char * word=malloc(BUFFER_CAP);  // DONT ENTER ANY LONG WORDS!
        printf("Enter a word to insertAtFront: " );
        fflush( stdout );
        char * result = fgets( word, BUFFER_CAP, stdin );
        if (result==NULL) fatal("failure reading from stdin\n");
        strtok(word,"\n"); // overwrites '\n' with  '\0'
        insertAtFront( &head, word ); /* shallow copy string into list   */
        printList( head );
    }
    if (option == 'T' )
    {
        char * word=malloc(BUFFER_CAP);  // DONT ENTER ANY LONG WORDS!
        printf("Enter a word to insertAtTail: " );
        fflush( stdout );
        char * result = fgets( word, BUFFER_CAP, stdin );
        if (result==NULL) fatal("failure reading from stdin\n");
        strtok(word,"\n"); // overwrites '\n' with  '\0'
        insertAtTail( &head, word ); /* shallow copy string into list   */
        printList( head );
    }
        if (option == 'R' )
    {
        char * word=malloc(BUFFER_CAP);  // DONT ENTER ANY LONG WORDS!
        printf("Enter a word to remove: " );
        fflush( stdout );
        char * result = fgets( word, BUFFER_CAP, stdin );
        if (result==NULL) fatal("failure reading from stdin\n");
        strtok(word,"\n"); // overwrites '\n' with  '\0'
        removeNode( &head, word );
        printList( head );
        free( word ); // we were just using it for matching
    }
    if (option == 'S' )
    {
        char * word=malloc(BUFFER_CAP);  // DONT ENTER ANY LONG WORDS!
        printf("Enter a word to find: " );
        fflush( stdout );
        char * result = fgets( word, BUFFER_CAP, stdin );
        if (result==NULL) fatal("failure reading from stdin\n");
        strtok(word,"\n"); // overwrites '\n' with  '\0'
        if (searchNode( head, word ))
            fprintf(stderr, "%s FOUND\n",word );
        else
            fprintf(stderr, "%s NOT FOUND\n",word );
        printList( head );
        free( word ); // we were just using it for matching
    }
    if (option == 'F' ) // free the entire list (remember to set head to NULL)
    {
        freeList( &head );
        printList( head );
    }
    else if (option == 'Q' )
        exit( 0 );
} // END WHILE

return 0;
}
4

2 に答える 2

2

を使用してノードにメモリを割り当てる場合Node *new = malloc( sizeof(Node) );、ポインタにはメモリを割り当てますが、データには割り当てません。あなたはcharにもメモリを割り当てます:(それは単なるアイデアです)

new->word= malloc(sizeof(char)*(strlen(key) + 1));
strcpy(new->word, key)

key それ以外の場合は、動的にメモリを割り当てる必要があります。(あなたがするからfree(tmp->word);)

コードをもう少し入れたほうがいいと思います。どのように合格しkeyますか?

于 2013-02-08T17:55:17.470 に答える
0

ええ、以前の回答で示されているように、ノードにメモリを割り当てていますが、各ノードの単語にメモリを割り当てていません。場合によっては、セグメンテーション違反を引き起こすことなく機能する可能性があります。その時点で、要求していない「誰かの」メモリを使用しているため、そのメモリの場所が破損します。

于 2013-02-08T18:24:48.720 に答える