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

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

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

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

Q&A

3回答

2107閲覧

Segmentation fault: 11を解決したい

keita55555

総合スコア4

C

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

0グッド

2クリップ

投稿2020/04/09 10:50

編集2020/04/09 11:28

前提・実現したいこと

ここに質問の内容を詳しく書いてください。
Segmentation faultを解決したいのですが自分では全然できません。教えてください。

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

#include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> /* 関数のプロトタイプ宣言*/ unsigned char *read_ppm(char *fname, int *width, int *height); void save_pgm(char *fname, unsigned char *gray, int width, int height); void trans(unsigned char *src, unsigned char *out, int width, int height, int g[]); void edge5(unsigned char *src, unsigned char *out, int width, int height, int threshold); void edge6(unsigned char *src, unsigned char *out, int width, int height, int threshold); void edge7(unsigned char *src, unsigned char *out, int width, int height, int threshold); void edge8(unsigned char *src, unsigned char *out, int width, int height, int threshold); int getThreshold(int *hist,int n); int main(int argc, char* argv[]) { int width, height; /* 入力画像のサイズ*/ unsigned char *src, *out; /* 白黒画像:それぞれ入力用と出力用に対応*/ int th; int hist[256]; int x1,x2,y1,y2; x1=0; y1=0; int kadai = 0; /* 課題番号: 実行ファイルの引数で値を指定<== argv[3][0] (一文字) */ /* 入力ファイル名<== argv[1], 出力ファイル名<== argv[2] */ if(argc != 4){ printf("usage: %s <source-image.ppm> <output-image.pgm> <kadai No.>\n", argv[0]); return 0; } /* 課題番号*/ kadai = argv[3][0] - '0'; /* 1 文字目を数値化 */ /* カラー画像のファイルを白黒化して読み込み*/ src = read_ppm(argv[1], &width, &height); out=(unsigned char*)malloc(width *height); memset(hist,0,sizeof(hist)); if(kadai == 1){ /* 白黒化した入力画像の保存*/ save_pgm(argv[2], src, width, height); free(src); return 0; } /* 出力画像バッファの作成*/ out = (unsigned char *)malloc(width * height); switch(kadai){ case 5: /* エッジ検出: 図2(a) */ for(int i=0;i<width*height;i++){ hist[src[i]]++; } th=getThreshold(hist,256); edge5(src, out, width, height, th); break; case 6: /* エッジ検出: 図2(b) */ for(int i=0;i<width*height;i++){ hist[src[i]]++; } th=getThreshold(hist,256); edge6(src, out, width, height, th); break; case 7: /* エッジ検出: sobel */ for(int i=0;i<width*height;i++){ hist[src[i]]++; } th=getThreshold(hist,256); edge7(src, out, width, height, th); break; case 8: /* エッジ検出: ラプラシアン*/ for(int i=0;i<width*height;i++){ hist[src[i]]++; } th=getThreshold(hist,256); edge8(src, out, width, height, th); break; default: fprintf(stderr, "正しい課題番号を指定してください!\n"); free(src); free(out); return -1; } /* 出力画像の保存*/ save_pgm(argv[2], out, width, height); free(src); free(out); return 0; } int getThreshold(int *hist,int n) { int th; int i,j; double max; int sa,sb,da,db; double ma,mb,mt; double wa,wb,wt; double kai; max=(-1000.0); th=0; for(i=1;i<n-1;i++){ da=0; sa=0; for(j=0;j<i;j++){ da+=(hist[j]*j); sa+=hist[j]; } db=0; sb=0; for(j=i;i<n;j++){ db+=(hist[j]*j); sb+=hist[j]; } if(sa!=0.0) ma=(double)da/(double)sa; else ma=0.0; if(sb!=0.0) mb=(double)db/(double)sb; else mb=0.0; mt=(double)(da+db)/(double)(sa+sb); wa=(double)sa/(double)(sa+sb); wb=(double)sb/(double)(sa+sb); kai=wa*(ma-mt)*(ma-mt)+wb*(mb-mt)*(mb-mt); if(max<kai){ max=kai; th=i; } } return th; } void trans(unsigned char *src, unsigned char *out, int width, int height, int g[]) { int x, y, i; for(y = 0; y < height; y++){ for(x = 0; x < width; x++){ i = width * y + x; out[i] = g[src[i]]; } } return; } void edge5(unsigned char *src, unsigned char *out, int width, int height, int threshold) { int x, y, i, val; int op[9] = {-1, 0, 1, -2, 0, 2, -1, 0, 1}; /* 上下左右の縁*/ for(x = 0; x < width; x++){ out[x] = 0; /* 上端*/ out[width*(height-1) + x] = 0; /* 下端*/ } for(y = 1; y < height-1; y++){ out[width * y] = 0; /* 左端*/ out[width * y + width-1] = 0; /* 右端*/ } /* 内側の処理*/ for(y = 1; y < height-1; y++){ for(x = 1; x < width-1; x++){ i = width * y + x; val = op[0] * src[i - width -1] + op[1] * src[i - width] + op[2] * src[i - width + 1] + op[3] * src[i -1] + op[4] * src[i ] + op[5] * src[i + 1] + op[6] * src[i + width -1] + op[7] * src[i + width] + op[8] * src[i + width + 1]; /* 2 値化*/ } } } void edge6(unsigned char *src, unsigned char *out, int width, int height, int threshold) { int x, y, i, val; int op[9] = {-1, -2, -1, 0, 0, 0, 1, 2, 1}; /* 上下左右の縁*/ for(x = 0; x < width; x++){ out[x] = 0; /* 上端*/ out[width*(height-1) + x] = 0; /* 下端*/ } for(y = 1; y < height-1; y++){ out[width * y] = 0; /* 左端*/ out[width * y + width-1] = 0; /* 右端*/ } /* 内側の処理*/ for(y = 1; y < height-1; y++){ for(x = 1; x < width-1; x++){ i = width * y + x; val = op[0] * src[i - width -1] + op[1] * src[i - width] + op[2] * src[i - width + 1] + op[3] * src[i-1] + op[4] * src[i] + op[5] * src[i + 1] + op[6] * src[i + width - 1] + op[7] * src[i + width] + op[8] * src[i + width + 1]; /* 2 値化*/ if(val >= threshold) out[i] = 255; else out[i] = 0; } } return; } void edge7(unsigned char *src, unsigned char *out, int width, int height, int threshold) { int x, y, i, val2,val, FX,FY; int fx[9] = {-1, 0, 1, -2, 0, 2, -1, 0, 1}; int fy[9] = {-1, -2, -1, 0, 0, 0, 1, 2, 1}; /* 上下左右の縁*/ for(x = 0; x < width; x++){ out[x] = 0; /* 上端*/ out[width*(height-1) + x] = 0; /* 下端*/ } for(y = 1; y < height-1; y++){ out[width * y] = 0; /* 左端*/ out[width * y + width-1] = 0; /* 右端*/ } /* 内側の処理*/ for(y = 1; y < height-1; y++){ for(x = 1; x < width-1; x++){ i = width * y + x; FX = fx[0] * src[i - width -1] + fx[1] * src[i - width] + fx[2] * src[i - width + 1] + fx[3] * src[i -1] + fx[4] * src[i ] + fx[5] * src[i + 1] + fx[6] * src[i + width -1] + fx[7] * src[i + width] + fx[8] * src[i + width + 1]; FY = fy[0] * src[i - width -1] + fy[1] * src[i - width] + fy[2] * src[i - width + 1] + fy[3] * src[i -1] + fy[4] * src[i ] + fy[5] * src[i + 1] + fy[6] * src[i + width -1] + fy[7] * src[i + width] + fy[8] * src[i + width + 1]; val2=(FX * FX+FY * FY); val=sqrt(val2); /* 2 値化*/ if(val >= threshold) out[i] = 255; else out[i] = 0; } } return; } void edge8(unsigned char *src, unsigned char *out, int width, int height, int threshold) { int x, y, i, val; int op[9] = {1,1,1,1,-8,1,1,1,1}; /* 上下左右の縁*/ for(x = 0; x < width; x++){ out[x] = 0; /* 上端*/ out[width*(height-1) + x] = 0; /* 下端*/ } for(y = 1; y < height-1; y++){ out[width * y] = 0; /* 左端*/ out[width * y + width-1] = 0; /* 右端*/ } /* 内側の処理*/ for(y = 1; y < height-1; y++){ for(x = 1; x < width-1; x++){ i = width * y + x; val = op[0] * src[i - width -1] + op[1] * src[i - width] + op[2] * src[i - width + 1] + op[3] * src[i -1] + op[4] * src[i ] + op[5] * src[i + 1] + op[6] * src[i + width -1] + op[7] * src[i + width] + op[8] * src[i + width + 1] ; if(val < 0) val = -val; /* 2 値化*/ if(val >= threshold) out[i] = 255; else out[i] = 0; } } return; } unsigned char *read_ppm(char *fname, int *width, int *height) { char str[256], c; int max = 0; unsigned char *gray = NULL; int r = 0, g = 0, b = 0; int size = 0; int i; FILE *fp = fopen(fname,"rb"); if(fp == NULL){ fprintf(stderr, "error: %s cannot open!", fname); exit(-1); } /* ------------ Magic number ---------- */ fscanf(fp, "%s", str); c = str[1]; if(c == '3' || c == '6'){ /* ------------ comment, space, or size ---------- */ fscanf(fp, "%s", str); if(str[0] == '#' || str[0] == '\n' ){ while(fscanf(fp,"%c",&str[0])){ /* comment skip */ if(str[0] == '\n') break; } fscanf(fp, "%d %d", width, height); } else{ sscanf(str, "%d", width); fscanf(fp, "%d", height); } /* ------------ comment, space, or max value ---------- */ fscanf(fp, "%d", &max); /* ------------ memory create ---------- */ size = (*width) * (*height); gray = (unsigned char *)malloc(size); /* ------------ pixel value ---------- */ if(c == '3'){ /* テキストデータ */ for(i = 0; i < size; i++){ fscanf(fp, "%d %d %d", &r, &g, &b); gray[i] = (unsigned char)(0.299 * r + 0.587 * g + 0.114 * b + 0.5); } } else{ /* バイナリデータ */ fread(&r,1,1,fp); /* LF */ for(i = 0; i < size; i++){ fread(&r,1,1,fp); fread(&g,1,1,fp); fread(&b,1,1,fp); gray[i] = (unsigned char)(0.299 * r + 0.587 * g + 0.114 * b + 0.5); } } } else fprintf(stderr, "[%s] is not a ppm-file!\n", fname); fclose(fp); return gray; } void save_pgm(char *fname, unsigned char *gray, int width, int height) { int x, y; FILE *fp = fopen(fname, "wb"); fprintf(fp, "P5\n"); fprintf(fp, "%d %d\n", width, height); fprintf(fp, "255\n"); for(y = 0; y < height; y++){ for(x = 0; x < width; x++) /*fprintf(fp, "%d ", gray[width * y + x]); fprintf(fp, "\n")*/ fwrite(&gray[width * y + x],sizeof(unsigned char),1,fp); } fclose(fp); return; } ```Segmentation fault: 11

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

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

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

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

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

y_waiwai

2020/04/09 10:58

このままではコードが読めないので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
fiveHundred

2020/04/09 11:09

PythonやC#とは全く関係のない質問なので、該当のタグを削除してください。
keita55555

2020/04/09 11:28

これで大丈夫でしょうか?すいません
guest

回答3

0

プログラムの中身までよく見ていないのですが、当方の環境 (Windows10 Visual Studio 2019) で適当なppmで実行してみると、

getThreshold()関数で不正アクセスの例外が発生しました。

c

1for (j = i; i < n; j++) {

c

1for (j = i; j < n; j++) {

が正しいのではないでしょうか?

そこを修正すると、出力されたppmが正しいかどうかは検証していませんが、最後まで実行できました。

投稿2020/04/10 02:53

Bull

総合スコア986

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

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

0

解答、ではないですが、解決するための方法を書いておきます。

LinuxであればEclipse、WindowsであればVisualStudioなどで、C言語のソースコードデバッグができます。
任意の行で実行を止め、変数のナカミを参照し、そこから1行づつ実行する事ができるようになります。
こういうので、あなたのコードのデバッグを行いましょう。

んで、Segmentation faultというのは、どこかでメモリ破壊が起こっている、という通知です。
残念ながらC言語では、メモリ破壊や範囲外アクセスなども含めて実行時エラーを確実に検出することは出来ません
ここでSegmentation faultがでているのは、あくまで運良くシステム側でエラーを検出できただけ、というのを肝に銘じてください

同じコードでも条件が変わるとエラーを検知できなくなったりは普通に起こります。

投稿2020/04/09 13:33

y_waiwai

総合スコア88042

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

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

0

経験的には、この手のプログラムでSegmentation faultが出る場合の殆どは添字の扱いの間違いです。(ところで、Segmentation faultがなんなのかはなんとなくでもわかっていますね?)

まず、配列の添字の扱いが間違っていないか(最大値を超えないか、負にならないか)徹底的にチェックして下さい。
間違いがない、と断言出来るのなら、次を考えましょう。

もちろんチェックするのはあなたですよ


小さな(30x10)サイズの画像を作って試してみましたが、そのサイズでは特にエラーは発生しませんでした。あなたのてもとでエラーが発生する条件を明確にして下さい。場合によってはデータファイル の正当性についても考えなければいけないかもしれません。

ppm

1P3 2# 330 10 4255 5255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 60 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 70 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 8255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 90 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 100 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 11255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 120 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 130 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 14255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 150 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 160 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 17255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 180 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 190 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 20255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 210 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 220 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 23255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 240 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 250 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 26255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 270 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 280 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 29255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 300 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 310 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 32255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 330 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 340 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255

投稿2020/04/09 11:47

編集2020/04/09 12:10
thkana

総合スコア7703

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

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

pepperleaf

2020/04/09 12:20

デバッガ上で実行できれば、デバッガが問題個所を教えてくれるのではないかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問