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

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

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

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

Q&A

解決済

2回答

960閲覧

Segmentation fault が出る理由がわかりません。

tsubo_NNN

総合スコア11

C

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

0グッド

0クリップ

投稿2019/05/08 10:53

整数データを連結リストに法則通り格納することを考えてます。

C言語で奇数のデータ同士は昇順に,偶数のデータ同士は降順に並ぶようにリストに挿入する機能を実装中に以下のエラーメッセージが発生しました。

Segmentation fault

該当のソースコード

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

typedef struct _cell{
int data;
struct _cell *next;
}CELL;

CELL *head;

void show_list()
{
CELL *p;
for(p=head;p!=NULL;p=p->next)
printf("%d\n",p->data);
}

void insert_cell(CELL *p,int d)
{
CELL new_cell;
new_cell = (CELL
)malloc(sizeof(CELL));
new_cell -> data = d;
new_cell -> next = p->next;
p -> next = new_cell;
}

void insert_cell_top(int d)
{
CELL new_cell;
new_cell = (CELL
)malloc(sizeof(CELL));
new_cell -> data = d;
new_cell -> next = head;
head = new_cell;
}

void insert_data(int d)
{
printf("insert_start\n");
if(head == NULL)
insert_cell_top(d);
else
{
CELL *p = head;
CELL *q = head -> next;
if(d%2==1){
while(q!= NULL&&q->data<d&&q->data%2==1){
p = q;
q = q -> next;
}
}
else{
while(q->data%2==1){
p = q;
q = q -> next;
}
while(q->data>=d&&q!=NULL){
p = q;
q = q -> next;
}

} printf("pointer_set\n"); if(p==head){ if(head->data!=d){ if(head->data%2==0&&d%2==0&&d>head->data)insert_cell_top(d); if(head->data%2==0&&d%2==0&&d<head->data)insert_cell(p,d); if(head->data%2==1&&d%2==1&&d<head->data)insert_cell_top(d); if(head->data%2==1&&d%2==1&&d>head->data)insert_cell(p,d); if(head->data%2==0&&d%2==1)insert_cell_top(d); if(head->data%2==1&&d%2==0)insert_cell(p,d); }else insert_cell(p,d); }else insert_cell(p,d); }

printf("insert_end\n");
}

int main(void)
{
clock_t start,end;
int i;
int x[10];
srand(time(NULL));
for(i=0;i<10;i++){
x[i]=rand()%10;
printf("%d\n",x[i]);
}
start=clock();
for(i=0;i<10;i++){
insert_data(x[i]);
}
end=clock();
printf("%f sec\n",(double)(end-start)/CLOCKS_PER_SEC);
show_list();
return 0;
}

C

試したこと

どこで動作しなくなっているのかみつけたが色々しても治らなかった。

補足情報(FW/ツールのバージョンなど)

while(q->data%2==1){
p = q;
q = q -> next;
}
while(q->data>=d&&q!=NULL){
p = q;
q = q -> next;
}

この部分でSegmentation faultがでていた。

全然わかりません。お力添えいただけますと幸いです、よろしくお願いします。

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

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

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

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

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

yumetodo

2019/05/08 11:02

ソースコードはmarkdownのcode block記法(```で行を囲う)を利用してください。
guest

回答2

0

ベストアンサー

一つのリストに対し何度もループするより, 偶数奇数でそれぞれリストを作って繋げるほうが, コードがすっきりしてNULLチェック抜け等しにくくなるかと思います.
最後に繋げる必要が出てきますが.

お風呂で考え直しましたら, 並び替え条件をちゃんと考えれば1本のリストでもすっきりできました.

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <time.h> 4 5typedef struct _cell { 6 int data; 7 struct _cell *next; 8} CELL; 9CELL *head = NULL; 10 11void show_list() { 12 for(CELL *p=head; p != NULL; p=p->next) printf("%d\n", p->data); 13} 14 15void insert_cell(CELL *p, int d) { 16 CELL *new_cell = (CELL *)malloc(sizeof(CELL)); 17 new_cell->data = d; 18 new_cell->next = p->next; 19 p->next = new_cell; 20} 21 22//奇数なら !0 を返す. 23int isOdd(int v) { return v%2; } 24//奇数の挿入位置で !0 を返す. 25int odd_order(int a, int b) { return isOdd(b) && a<b; } 26//偶数の挿入位置で !0 を返す. 27int even_order(int a, int b) { return isOdd(b) || a>b; } 28 29void insert_data(int d) { 30 printf("insert_start\n"); 31 int (*order)(int, int) = isOdd(d) ? odd_order : even_order; 32 CELL h = { .next = head }; //先頭への挿入の簡略化のため 33 34 CELL *p = &h; 35 for( ; p->next != NULL; p=p->next) { 36 if(order(d, p->next->data)) break; 37 } 38 printf("pointer_set\n"); 39 insert_cell(p, d); 40 head = h.next; 41 printf("insert_end\n"); 42} 43 44int main(void) { 45 clock_t start, end; 46 int i; 47 int x[10]; 48 49 srand(time(NULL)); 50 for(i=0; i<10; i++) { 51 x[i] = rand() % 10; 52 printf("%d\n", x[i]); 53 } 54 55 start = clock(); 56 for(i=0; i<10; i++) { 57 insert_data(x[i]); 58 } 59 end = clock(); 60 printf("%f sec\n", (double)(end-start)/CLOCKS_PER_SEC); 61 62 show_list(); 63 return 0; 64}

投稿2019/05/08 15:51

編集2019/05/09 01:35
jimbe

総合スコア12646

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

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

0

c

1 while(q->data%2==1){ 2 p = q; 3 q = q -> next; 4 } 5 while(q->data>=d&&q!=NULL){ 6 p = q; 7 q = q -> next; 8 }

qに対するNULLチェックをやっていないorするまえにqをdereferenceしていますよね/

投稿2019/05/08 11:02

yumetodo

総合スコア5850

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問