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

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

新規登録して質問してみよう
ただいま回答率
85.37%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C

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

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

GDB

GDBはGNUソフトウェアシステムのための標準的なデバッガーです。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

Q&A

解決済

4回答

4894閲覧

'Program received signal SIGSEGV, Segmentation fault.'の解決

Mellonn

総合スコア3

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C

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

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

GDB

GDBはGNUソフトウェアシステムのための標準的なデバッガーです。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

0グッド

0クリップ

投稿2021/10/31 20:22

編集2021/11/01 05:23

前提・実現したいこと

オープンアドレス法というハッシュ法をCで実装しようとしています.

環境はWindows10上のUbuntu 20.04.2 LTSです.

エラーメッセージはgdbを利用してトレースした際に出たものです.

open_addressing.cのcreate_dict関数に問題があることはわかるのですが,具体的な箇所がわからず困っています.

わかる方いましたらお願いします.

発生している問題・エラーメッセージ

$ ./a.out Breakpoint 1, main () at main_open_addressing.c:5 5 int main(void) { (gdb) step 6 DictOpenAddr *test_dict = create_dict(10); (gdb) step create_dict (len=0) at open_addressing.c:7 warning: Source file is more recent than executable. 7 { (gdb) step 8 DictOpenAddr *dictopenaddr = (DictOpenAddr *)malloc(sizeof(DictOpenAddr)); (gdb) step Dictionary created! Program received signal SIGSEGV, Segmentation fault.

該当のソースコード

<open_addresing.c>

C

1#include <stdio.h> 2#include <stdlib.h> 3#include "open_addressing.h" 4#include "main_open_addressing.c" 5 6DictOpenAddr *create_dict(int len) 7{ 8 DictOpenAddr *dictopenaddr = (DictOpenAddr *)malloc(sizeof(DictOpenAddr)); 9 10 dictopenaddr->H = (DictData *)malloc(sizeof(DictData) * len); 11 dictopenaddr->B = len; 12 13 for (int i=0; i < len; i++) 14 { 15 dictopenaddr->H[i].name = -1; 16 dictopenaddr->H[i].state = EMPTY; 17 } 18 19 printf("Dictionary created!\n"); 20 21 return dictopenaddr; 22} 23 24int h(DictOpenAddr *dict, int d, int count){ 25 26 int hash = d % (dict->B); 27 28 hash = (hash + count) % (dict->B); 29 30 return hash; 31} 32 33void insert_hash(DictOpenAddr *dict, int d) 34{ 35 if (search_hash(dict,d) != -1 ) 36 { 37 return ; 38 } 39 40 int count = 0; 41 int b = h(dict,d,count); 42 int init_b = b; 43 44 while (b != init_b){ 45 if (dict->H[b].state == EMPTY || dict->H[b].state == DELETED) 46 { 47 dict->H[b].name = d; 48 dict->H[b].state = OCCUPIED; 49 } 50 51 count += 1; 52 b = h(dict,d,count); 53 } 54 55 fprintf(stderr, "Cannot be inserted.\n"); 56} 57 58int search_hash(DictOpenAddr *dict, int d) 59{ 60 int count = 0; 61 int b = h(dict,d,count); 62 int init_b = b; 63 64 while (b != init_b){ 65 if (dict->H[b].state == OCCUPIED) 66 { 67 if (dict->H[b].name == d) 68 { 69 return b; 70 } 71 72 } 73 74 else if ((dict->H)[b].state == EMPTY) 75 { 76 return -1; 77 } 78 79 count += 1; 80 81 b = h(dict,d,count); 82 83 84 } 85 return -1; 86 } 87 88void delete_hash(DictOpenAddr *dict, int d) 89{ 90 int b = search_hash(dict,d); 91 if (b != -1) 92 { 93 (dict->H)[b].state = DELETED; 94 } 95} 96 97void display(DictOpenAddr *dict) 98{ 99 int i = 0; 100 101 while (i<dict->B){ 102 switch (dict->H[i].state) 103 { 104 case EMPTY: 105 printf("e"); 106 case DELETED: 107 printf("d"); 108 case OCCUPIED: 109 printf("%d",dict->H[i].name); 110 } 111 i++; 112 } 113} 114 115void delete_dict(DictOpenAddr *dict){ 116 free(dict); 117 printf("Dictionary deleted!"); 118}

<open_addresing.h>

C

1#ifndef INCLUDE_GUARD_OPEN_ADDRESSING_H 2#define INCLUDE_GUARD_OPEN_ADDRESSING_H 3 4typedef enum state { 5 EMPTY, 6 DELETED, 7 OCCUPIED 8} State; 9 10typedef struct dict_data { 11 int name; 12 State state; 13} DictData; 14 15typedef struct dict_open_addr { 16 DictData *H; 17 int B; 18} DictOpenAddr; 19 20DictOpenAddr *create_dict(int len); 21int h(DictOpenAddr *dict, int d, int count); 22void insert_hash(DictOpenAddr *dict, int d); 23int search_hash(DictOpenAddr *dict, int d); 24void delete_hash(DictOpenAddr *dict, int d); 25void display(DictOpenAddr *dict); 26void delete_dict(DictOpenAddr *dict); 27 28#endif // INCLUDE_GUARD_OPEN_ADDRESSING_H

<main_open_addresing.c>

C

1#include <stdio.h> 2#include <stdlib.h> 3#include "open_addressing.h" 4 5int main(void) { 6 DictOpenAddr *test_dict = create_dict(10); 7 8 insert_hash(test_dict, 1); 9 insert_hash(test_dict, 2); 10 insert_hash(test_dict, 3); 11 insert_hash(test_dict, 11); 12 insert_hash(test_dict, 12); 13 insert_hash(test_dict, 21); 14 display(test_dict); 15 16 printf("Search 1 ...\t%d\n", search_hash(test_dict, 1)); 17 printf("Search 2 ...\t%d\n", search_hash(test_dict, 2)); 18 printf("Search 21 ...\t%d\n", search_hash(test_dict, 21)); 19 printf("Search 5 ...\t%d\n", search_hash(test_dict, 5)); 20 21 delete_hash(test_dict, 3); 22 display(test_dict); 23 24 delete_hash(test_dict, 11); 25 display(test_dict); 26 27 delete_dict(test_dict); 28 29 return EXIT_SUCCESS; 30}

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

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

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

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

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

guest

回答4

0

C言語ってのは、実行時のエラーチェックは基本的に行いません
そのため、実行時のエラーというのは、たまたまそこでその内容で引っかかっただけ、なんで、発生場所やエラー内容はそのまま信用できないのが普通です。

ってことで、あなたのコードの中でアクセス違反や異常アクセスがあります。
ガンバってその場所を特定しましょう。

#コードが一部しか提示されてないので、言えるのはここまで

投稿2021/10/31 23:33

y_waiwai

総合スコア88024

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

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

Mellonn

2021/10/31 23:41

自分が訂正している箇所(create_dict)以外にアクセスに関する問題がある可能性があるということですね. 訂正してコード全体を載せます.自分でも見直します.
y_waiwai

2021/10/31 23:43

メモリ破壊があるために、プログラムが暴走して、たまたまそのSIGSEGVで止まった、というところでしょうね。
guest

0

そのcreate_dictならdictopenaddrの指す先はmallocで確保しとく必要がある。
変数定義の時に、初期化を伴う様にすれば気付きやすいかも。

投稿2021/10/31 23:30

matukeso

総合スコア1677

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

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

Mellonn

2021/10/31 23:37

dictopenaddr先の領域もmallocで確保しておきました.
Mellonn

2021/10/31 23:38

↑修正後のことです
matukeso

2021/11/01 00:50

warning: Source file is more recent than executable ソース変更しただけでコンパイルしてないオチ?
Mellonn

2021/11/01 03:05

コンパイルし直しました 質問文にあるように,'Dictionary created!'の出力まではいきましたが,その直後にSegmentation faultが出ました
matukeso

2021/11/01 04:15

cc -c -o open_addressing.o open_addressing.c ./a.out 今度はリンクしてないオチ?というかビルド方法わからないの?
Mellonn

2021/11/01 05:21

Makefile(open_addressing: open_addressing.o main_open_addressing.o)をmakeして,/a.outを行っているのですが,何か足りない作業などありますか?
matukeso

2021/11/01 06:40

なんでそのMakefileでa.outになるの? ./open_addressingじゃなくて? (.c.o:ルールがある前提)
Mellonn

2021/11/01 09:08

Makefile上でtypoがありました 修正して,makeしてみたところ cc -c -o open_addressing.o open_addressing.c cc -c -o main_open_addressing.o main_open_addressing.c cc open_addressing.o main_open_addressing.o -o open_addressing /usr/bin/ld: main_open_addressing.o: in function `main': main_open_addressing.c:(.text+0x0): multiple definition of `main'; open_addressing.o:open_addressing.c:(.text+0x0): first defined here collect2: error: ld returned 1 exit status make: *** [<builtin>: open_addressing] Error 1
matukeso

2021/11/01 09:33

そのリンカエラーによれば、open_addressing.cとmain_open_addressing両方にmain関数が書いてある事になるんですが、、
Mellonn

2021/11/01 10:00

すいません。open_addressing.cにmain_open_addressing.cをインクルードしていたのが原因みたいでした
guest

0

DictOpenAddr *dictopenaddr;// 初期化されていないポインタが指す(不正な)要素に

dictopenaddr->H = DDp;// 値を
dictopenaddr->B = len;// 代入しています

投稿2021/10/31 23:29

episteme

総合スコア16612

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

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

Mellonn

2021/10/31 23:39

修正して,ポインタdictopenaddrもmallocで初期化しておきました
episteme

2021/11/01 00:16

それにより問題は解決しなかったってことですか?
Mellonn

2021/11/01 03:06

再度修正した質問文にあるように,'Dictionary created!'の出力まではいきましたが,その直後にSegmentation faultが出ました
episteme

2021/11/01 03:14 編集

gdbのいう通り、printf(nchr); が問題なんでしょうよ。 # ...おっと、いつのまにか質問が変わってる
Mellonn

2021/11/01 05:22

switch文は修正しました. 質問内容は解決しました.ありがとうございました.
episteme

2021/11/01 10:31

解決したならcloseしといて。
guest

0

自己解決

DictOpenAddr型のメモリ領域を確保したことで解決

投稿2021/11/02 04:21

Mellonn

総合スコア3

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

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

int32_t

2021/11/02 04:26

自分だけの力で解決したのでなければ、他の方による回答からベストアンサーを選んでください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問