キューを使った双方向リストに関するプロセス処理


Aizu Online JudgeのALDS1_3_Cの問題を解いています。

[双方向連結リスト | アルゴリズムとデータ構造 | Aizu Online
Judge](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_3_C&lang=jp)

原因不明のエラーに悩んでいます。以下がソースコードになります。

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define QUEUE_SIZE 2000000
    #define next(x) ((x + 1) % QUEUE_SIZE)
    
    struct job {
        char *command;
        int key;
    } jobs[QUEUE_SIZE];
    
    struct cell {
        int key;
        struct cell *prev;
        struct cell *next;
    } head;
    
    int front, rear;
    
    void init(void);
    void enqueue(char *command,  int key);
    struct job dequeue(void);
    void insert(int key);
    void delete(int key);
    void deleteFirst(void);
    void deleteLast(void);
    
    int main(void)
    {
        int n, key;
        char *command;
        struct cell *p;
    
        scanf("%d", &n);
        init();
        for (int i = 0; i < n; i++) {
            scanf("%s %d", command, &key);
            enqueue(command, key);
        }
    
        while (front != rear) {
            struct job deq = dequeue();
            if (deq.command == "insert") {
                insert(deq.key);
            } else if (deq.command == "delete") {
                delete(deq.key);
            } else if (deq.command == "deleteFirst") {
                deleteFirst();
            } else if (deq.command == "deleteLast") {
                deleteLast();
            } else {
                exit(1);
            }
        }
    
        // リスト出力
        for (p = head.next; p != NULL; p = p->next) {
            printf("%d ", p->key);
        }
        printf("\n");
        return 0;
    }
    
    void init(void)
    {
        front = rear = 0;
    }
    
    void enqueue(char *command, int key)
    {
        if (next(rear) == front) {
            fprintf(stderr, "queue is full.");
            exit(1);
        }
        jobs[rear].command = (char *)malloc(sizeof(char) * sizeof(command) + 1);
        strcpy(jobs[rear].command, command);
        jobs[rear].key = key;
        rear = next(rear);
    }
    
    struct job dequeue()
    {
        struct job deq;
        if (front == rear) {
            fprintf(stderr, "queue is empty.\n");
            exit(1);
        }
        deq = jobs[front];
        front = next(front);
        return deq;
    }
    
    void insert(int key)
    {
        struct cell *new;
        new->key = key;
        new->next = head.next;
        new->prev = &head;
        head.next = new;
    }
    
    void delete(int key)
    {
        struct cell *p;
        if (head.next == NULL) {
            fprintf(stderr, "doubly linked list is empty.\n");
            exit(1);
        }
        p = head.next;
        while (p != NULL && p->key != key) {
            p = p->next;
        }
        p->prev->next = p->next;
        p->next->prev = p->prev;
    }
    
    void deleteFirst()
    {
        if (head.next == NULL) {
            fprintf(stderr, "doubly linked list is empty.\n");
            exit(1);
        }
        head.next->next->prev = &head;
        head.next = head.next->next;
    }
    
    void deleteLast()
    {
        if (head.next == NULL) {
            fprintf(stderr, "doubly linked list is empty.\n");
            exit(1);
        }
        struct cell *p;
        p = head.next;
        while (p->next != NULL) {
            p = p->next;
        }
        p->prev->next = NULL;
    }
    
[/code]

ここで、main関数内でstruct job
型の変数を宣言すると、scanf関数で入力を受け取れなくなります。試しにmain関数のwhile文以下をコメントアウトして、実行すると受け取れました。main関数内でstruct
job型の変数を宣言すると、途端に2つ目のscanf関数で入力を受け取れなくなるのです。解決策を教えて下さい。




いわゆる「メモリ破壊」が発生していることの副作用と考えます。  
以下の箇所で「`command`」がポインタで、かつ初期化していないため、`scanf()`の結果が異常な場所に格納されているため、後続の処理が正常に動作しないものと予想します。

変数`command`を配列として宣言するか、`malloc()`等で動的に確保した領域を指すように修正することで、事象は解消するものと思います。

[code]

        int n, key;
        char *command;
        struct cell *p;
    
        scanf("%d", &n);
        init();
        for (int i = 0; i < n; i++) {
            scanf("%s %d", command, &key);
            enqueue(command, key);
        }
    
[/code]

* * *

なお、以下の比較文も実装が誤っているので、`strcmp()`等で文字列比較する必要があると思います。

[code]

           if (deq.command == "insert") {
                insert(deq.key);
            } else if (deq.command == "delete") {
                delete(deq.key);
            } else if (deq.command == "deleteFirst") {
                deleteFirst();
            } else if (deq.command == "deleteLast") {
                deleteLast();
            } else {
                exit(1);
            }
    
[/code]

