リスト構造を用いたQUEUE

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
いあ

リスト構造を用いたQUEUE

#1

投稿記事 by いあ » 7年前

このプログラムを動かすとEnqueueのWhileでアクセス違反と出て止まりますが、解決策がわかりません。
どこを説明すればいいかわからないので適宜回答します

コード:

#include <stdio.h>
#include<stdlib.h>
#define _CRT_CECURE_NO_WARNING
struct node_t {
	int data;
	struct node_t *next;
};
typedef struct node_t Node;

Node *head = NULL;
Node *tail = NULL;
Node *ND;
int count=0;

Node *new_node(int data) {
	Node *nd = (Node *)malloc(sizeof(Node));
	if (nd == NULL) {
		printf("malloc for NODE* failed.\n");
		exit(1);
	}
	nd->data = data;
	nd->next = tail;
	ND = nd;//return ndだとうごかせない?
	return 0;

}

void enqueue(Node *node) {
	Node *last = (Node *)malloc(sizeof(Node));
	if (head == NULL) {
		last->data = ND->data;
		last->next = tail;
		head = ND;
		last = ND;
	}else {
		while (last->next != NULL)
			last = last->next;
		last->next = ND;
	}
	count++;
}

Node *dequeue() {
	Node *p = head;
	head = head->next;
	return p;
}

void print_queue(void) {
	Node *e = (Node *)malloc(sizeof(Node));
	for (int i = 0; i < count; i++) {
		printf("| %d ", e->data);
	}
	printf("\n");
}

int main(void)
{
	Node *e;

	printf("enqueue(new_node(1000))\n");
	enqueue(new_node(1000));
	printf("enqueue(new_node(2000))\n");
	enqueue(new_node(2000));
	printf("enqueue(new_node(3000))\n");
	enqueue(new_node(3000));
	printf("enqueue(new_node(4000))\n");
	enqueue(new_node(4000));
	printf("enqueue(new_node(5000))\n");
	enqueue(new_node(5000));
	print_queue();
	printf("\n");

	e = dequeue();
	printf("dequeue-> %d\n", e->data);
	print_queue();
	free(e);
	e = dequeue();
	printf("dequeue-> %d\n", e->data);
	print_queue();
	free(e);
	e = dequeue();
	printf("dequeue-> %d\n", e->data);
	print_queue();
	free(e);

	free(head);

	return 0;
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: リスト構造を用いたQUEUE

#2

投稿記事 by みけCAT » 7年前

エラーの原因は、mallocで確保して初期化していない(不定の)last->nextをlastに大入し、デリファレンスした(未定義動作)ことでしょう。
このwhile文の前にlast = head; を入れると改善しそうですね。

…しかし、引数を計算する関数内で確保した領域へのポインタを一旦グローバル変数に代入し、
その引数を受け取る関数では引数をガン無視して(普通のローカル変数としてすら使わずに)グローバル変数から値を取り出して計算するとは、独創的で面白いコードですね。
print_queue関数も、不定の(同じ?)値をcount回出力して、何がしたいのでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: リスト構造を用いたQUEUE

#3

投稿記事 by かずま » 7年前

解決策です。

コード:

#include <stdio.h>
#include <stdlib.h> // malloc, free, exit

struct node_t {
    int data;
    struct node_t *next;
};
typedef struct node_t Node;
 
Node *head = NULL;
Node *tail = NULL;
//int count = 0;
 
Node *new_node(int data)
{
    Node *nd = (Node *)malloc(sizeof(Node));
    if (nd == NULL) puts("malloc for NODE* failed."), exit(1);
    nd->data = data;
    nd->next = NULL;
    return nd;
}
 
void enqueue(Node *node)
{
    if (head == NULL) head = node;
    else tail->next = node;
    tail = node;
    // count++;
}
 
Node *dequeue(void)
{
    Node *p = head;
    if (!p) puts("queue empty"), exit(1);
    head = head->next;
    if (!head) tail = NULL;
    // count--;
    return p;
}
 
void print_queue(void)
{
    for (Node *e = head; e; e = e->next)
        printf("| %d ", e->data);
    printf("\n");
}

int main(void)
{
    Node *e;
 
    printf("enqueue(new_node(1000))\n"); enqueue(new_node(1000));
    printf("enqueue(new_node(2000))\n"); enqueue(new_node(2000));
    printf("enqueue(new_node(3000))\n"); enqueue(new_node(3000));
    printf("enqueue(new_node(4000))\n"); enqueue(new_node(4000));
    printf("enqueue(new_node(5000))\n"); enqueue(new_node(5000));
    print_queue(); printf("\n");
 
    e = dequeue(); printf("dequeue-> %d\n", e->data); print_queue(); free(e);
    e = dequeue(); printf("dequeue-> %d\n", e->data); print_queue(); free(e);
    e = dequeue(); printf("dequeue-> %d\n", e->data); print_queue(); free(e);

    while (head) free(dequeue());

    return 0;
}
理解できないところは質問してください。

返信

“C言語何でも質問掲示板” へ戻る