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

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

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

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

ポインタ

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

Q&A

4回答

9702閲覧

ダブルポインタと構造体

indehi

総合スコア7

C

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

ポインタ

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

0グッド

0クリップ

投稿2016/06/10 14:07

編集2016/06/11 04:32

キューを使ってenqueue,dequeueするプログラムをポインタのポインタを引数に持つ関数で作りたいです。
deq操作を行う関数とキューの中をカラにする関数で警告がでます。無視して実行するとセグメンテーション違反になります。どう改良すればいいでしょうか。

訂正

lang

1void enq(struct LIST **head, struct cell **tail, int val,int n){ 2 struct LIST *p; 3 if(n==1){ 4 p = (struct LIST *)malloc(sizeof(struct LIST); 5 p->num = val; 6//ここでセグメンテーション違反になってしまいます。 7 p->next = NULL; 8 *head = *tail = p; 9 } 10 else{ 11 p = (struct LIST *malloc(sizeof(struct LIST)); 12 p->num = val; 13 p->next = NULL; 14 (*tail)->next = p; 15 *tail = p; 16 } 17} 18 19int deq(struct LSIT **head){ 20 int deqdata; 21 struct LSIT *p; 22 deqdata = (*head)->num; 23 p = *head;//警告 24 head = &(*head)->next; 25 free(p); 26 return deqdata; 27} 28 29 30void free_queue(struct LIST **head){ 31 struct LIST *p; 32if(head!=NULL) 33 free(p);//警告 34}

コンパイル
In function ‘deq’:
警告: assignment from incompatible pointer type
In function ‘free_queue’:
警告: ‘p’ may be used uninitialized in this function

ちゃんとコンパイルできたけどdeqを行ったら強制終了されました。

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

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

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

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

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

guest

回答4

0

セグメンテーション違反になっているところの説明だけしますね。
mallocはメモリを確保します。
返却されるのはその確保したメモリの先頭アドレスです。
提示のコードはそのアドレスをダブルポインタとして扱おうとしています。

ダブルポインタとは
int a;
int *pa = &a; // 実体のアドレス
int **ppa = &pa; // ポインタ変数のアドレス=ダブルポインタ

ダブルポインタの変数には、アドレスが入った変数のアドレスを入れないといけないところ、提示のコードでは領域の先頭アドレスを入れてしまっているのが原因です。
mallocで確保した領域は初期化されていませんから、先頭アドレスにある不定値をアドレスに見立てて参照しようとしてセグメンテーション違反になっています。
またmallocする領域のサイズもsizeof(struct cell *)では正しくありません。
struct cell * はアドレスですから、4バイト(32ビット環境)とか8バイト(64ビット環境)とかになります。
以下、サンプルです(修正方法ではありません)

c

1// 領域確保 2struct cell *p; 3p = (struct cell *)malloc(sizeof(struct cell)); 4p->num = val; 5 6// ダブルポインタでアクセス 7struct cell **pp; 8pp = &p; 9(*pp)->num = val; 10

投稿2016/06/10 15:30

ttyp03

総合スコア16998

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

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

0

こんにちは。

p = (struct cell **)malloc(sizeof(struct cell *));
(*p)->num = val;

sizeof(sruct cell*)はどんな値になると思いますか?
cell構造体へのポインタのサイズですので、4(32bitビルド)や8(64bitビルド)ですね。
cell構造体のサイズはわかりませんが、たぶん、8より大きく、かつ、numは8より後ろにあるのでは?

一部分だけザッと書いてみます。

C++

1struct cell *p; 2if(n==1){ 3 p = (struct cell *)malloc(sizeof(struct cell)); 4 p->num = val; 5 p->next = NULL; 6 *head = *tail = p; 7}

呼び出し側は、struct cell *head;のような定義で、enq(&head, ...);のように呼び出します。

投稿2016/06/10 14:32

編集2016/06/10 14:33
Chironian

総合スコア23272

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

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

0

まずenqもdeqも期待通りには動かないと思いますよ。

処理的にはdeqの前にenqが行われているはずなので、enqがうまく動かない以上、deqでの動作を期待するのは無理があります。ちなみに動的変数でない方法で試験用リストを作ってdeqを呼んだのならば当然エラー停止します。

投稿2016/06/10 14:28

HogeAnimalLover

総合スコア4830

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

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

0

ただの誤字かもしれませんがcelになってますよ。もしcell以外にcelという構造体宣言が存在していたらまずいです。

投稿2016/06/10 14:10

masaya_ohashi

総合スコア9206

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

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

indehi

2016/06/10 14:18

ただのごじでした。ありがとうざいます。 けどちゃんとコンパイルできませんでした。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問