質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

Q&A

1回答

3178閲覧

ダブルポインタでキューを作る

indehi

総合スコア7

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

0グッド

0クリップ

投稿2016/06/12 09:11

###作りたいプログラム
ポインタのポインタを利用し、構造体でキューを作成するプログラム。

lang

1#include<stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#define MAX 10 5struct LIST { 6 int num; 7 struct cell *next; 8}; 9struct LIST *p; 10 11void enq(struct LIST **head, struct LIST **tail, int val,int n){ 12 if(n==1){ 13 p = (struct LIST *)malloc(sizeof(struct LIST)); 14 p->num = val; 15 p->next = NULL; 16 *head = *tail = p; 17 } 18 else{ 19 p = (struct LIST *)malloc(sizeof(struct LIST)); 20 p->num = val; 21 p->next = NULL; 22 (*tail)->next = p; 23 *tail = p; 24 } 25} 26 27int deq(struct LIST **head){ 28 int deqdata; 29 deqdata = (*head)->num; 30 p = *head; 31 head = &(*head)->next; 32 free(p); 33 return deqdata; 34} 35 36void print_queue(struct LIST *head){ 37 p=head; 38 while(p!=NULL){ 39 printf("->%d",p->num); 40 p = p->next; 41 } 42 printf("\n"); 43} 44 45void free_queue(struct LIST **head){ 46if(head!=NULL) 47 free(p); 48} 49 50int main(void){ 51 char select[MAX]; 52 int data; 53 int n; 54 struct LIST *listhead=NULL; 55 struct LIST *listtail; 56 while(1){ 57 n++; 58 printf("%d回目の操作を選択してください",n); 59 scanf("%s",select); 60 if(strcmp(select,"enq")==0){ 61 printf("データを入力:"); 62 scanf("%d",&data); 63 enq(&listhead,&listtail,data,n); 64 print_queue(listhead); 65 } 66 67 else if(strcmp(select,"deq")==0){ 68 if(listhead ==NULL){ 69 printf("データがありません\n"); 70 return 0; 71 } 72else 73 printf("とり出されたデータ:%d\n",deq(&listhead)); 74 } 75 76 else if(strcmp(select,"end")==0){ 77 free_queue(&listhead); 78 return 0; 79 } 80 } 81} 82

###コンパイル
1回目の操作を選択してくださいenq
データを入力:3
->3
2回目の操作を選択してくださいenq
データを入力:7
->3->7
3回目の操作を選択してくださいenq
データを入力:7
->3->7->7
4回目の操作を選択してくださいdeq
とり出されたデータ:3
5回目の操作を選択してくださいdeq
*** glibc detected *** ./a.out: double free or corruption (fasttop): 0x0000000000601010 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x763b6)[0x7f210e3b03b6]
./a.out[0x40083c]
./a.out[0x4009c9]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x7f210e358b1d]
./a.out[0x400689]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:01 266382 /home/bp15106/prog1/a.out
00600000-00601000 rw-p 00000000 08:01 266382 /home/bp15106/prog1/a.out
00601000-00622000 rw-p 00000000 00:00 0 [heap]
7f210e124000-7f210e13a000 r-xp 00000000 08:01 1562 /lib64/libgcc_s-4.4.5.so.1
7f210e13a000-7f210e339000 ---p 00016000 08:01 1562 /lib64/libgcc_s-4.4.5.so.1
7f210e339000-7f210e33a000 rw-p 00015000 08:01 1562 /lib64/libgcc_s-4.4.5.so.1
7f210e33a000-7f210e4ab000 r-xp 00000000 08:01 1951 /lib64/libc-2.11.1.so
7f210e4ab000-7f210e6ab000 ---p 00171000 08:01 1951 /lib64/libc-2.11.1.so
7f210e6ab000-7f210e6af000 r--p 00171000 08:01 1951 /lib64/libc-2.11.1.so
7f210e6af000-7f210e6b0000 rw-p 00175000 08:01 1951 /lib64/libc-2.11.1.so
7f210e6b0000-7f210e6b5000 rw-p 00000000 00:00 0
7f210e6b5000-7f210e6d3000 r-xp 00000000 08:01 1932 /lib64/ld-2.11.1.so
7f210e8b8000-7f210e8bb000 rw-p 00000000 00:00 0
7f210e8cf000-7f210e8d2000 rw-p 00000000 00:00 0
7f210e8d2000-7f210e8d3000 r--p 0001d000 08:01 1932 /lib64/ld-2.11.1.so
7f210e8d3000-7f210e8d4000 rw-p 0001e000 08:01 1932 /lib64/ld-2.11.1.so
7f210e8d4000-7f210e8d5000 rw-p 00000000 00:00 0
7fff82cd6000-7fff82cf7000 rw-p 00000000 00:00 0 [stack]
7fff82dff000-7fff82e00000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
アボートしました

###エラー
2回めのdequeue操作でアボートされる


enqueue,dequeueの操作が正常に実行できるようにするにはどう改善すればいいですか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

こんにちは。

deq()のhead = &(*head)->next;はよろしくないです。
head = &(*head)->next;にてheadに値が設定されますが、これはdeq()関数の中だけ有効です。呼び出し元のlistheadへ反映されません。
つまり、deq()呼出し後も、listheadの値は変化しませんから、deq()でfree()したメモリを指したままです。2回目のdeq()でその領域をアクセスするため、アボートします。

*head=(*head)->next;で行けるのではないかと思います。

投稿2016/06/12 09:23

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

indehi

2016/06/12 09:49

書きなおしたらできました!でもどうしてhead = &(*head)->nextだとlistheadに反映されないのでしょうか。
Chironian

2016/06/12 09:57

C言語の関数は全て値渡しです。 つまり、deq()のパラメータとしてheadが渡されていますが、これは値渡しですので、(&listhead)の値、つまりlistheadの先頭アドレスが渡されるだけです。 そして、listheadと*headが同じものですので*headへの設定はlistheadへの設定となります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問