人に聞けない痔の悩み、これでスッキリ >>

Cプログラムを実行した時に発生する、セグメントエラー
は何が原因なのでしょうか?
コンパイルはちゃんとととっているのに、
なぜエラーがでるのでしょうか?
C言語の本を見たのですが、
のってません。
お願いします。

このQ&Aに関連する最新のQ&A

A 回答 (5件)

こんにちわ。



「セグメントエラー」ってSegmentation Fault の事ですよね。
そうであれば、メモリのアクセス侵害です。
原因としては、
・アクセスできない筈のアドレス (NULL アドレスとか) にアクセスした
・獲得したアドレスを越えてアクセスした。
・初期化していないポインタ変数を使ってアクセスした。
と言う感じです。

ケースとしては少ないと思いますが、1つの変数 (領域) を複数の
データ型でアクセスした場合に、起きる事があります。
    • good
    • 2
この回答へのお礼

ありがとうございます。アドレス関係の違反なのですか、
がんばって確認してみます。

お礼日時:2002/12/20 23:17

>ありがとうございます。


>NULLとは文字列の最後に入っているやつですね、
>絶対入れないといけないのですよね~?

文字列にかぎりませんよ。
ポインタなども使い回ししたりする場合はNULLで初期化すると良いです。
ポインタが開放したアドレスを覚えてたりして、そこにアクセスした瞬間コケるという事もあります。
基本的に確保した領域は何が入っているか分かりません、ですから初期化をお勧めしたのです。
    • good
    • 2
この回答へのお礼

ありがとうございます。
初期化は心がけます。

お礼日時:2002/12/25 13:15

No1、No2の方が書いておられるように、原因は様々ですが、


ひとつ例をあげると、
char a[5];
char b[10];   と領域を定義して、
strcpy( a, b ); と記述した場合、構文は問題ありませんよね。
コンパイルエラーは出ません。

でもいざ実行した時、bの値が"abcd"であれば問題ありませんが、
"abcdefgh"だったらaの領域をオーバーしてしまいます。

こういう場合に、そういうエラーが起こる場合があります。
メモリ領域は実行時に割り当てられる為、
aの領域の後ろがたまたま書き込んではいけないようになっている場合は
エラーが出ますし、書き込み可能の領域が割り振られている場合は、
何か別のデータを壊して上書きしてしまいます。

また、本を見られたようですが、この辺のことは言語というよりは、
OSの本のメモリ管理の説明のところに載っています。
    • good
    • 1
この回答へのお礼

ありがとうございます。
とてもくわしくて解かりやすかったです。

お礼日時:2003/01/04 20:45

ソースを見ていないのではっきりしたことはいえませんが、


コーディング時に気を付けることは、使用する変数は「必ず初期化を行う」を習慣づけることです。
ポインタや配列などは怠りがちになってしまいますが是非やってください。
NULLクリアしてあげるだけでもかなり違うと思います。
現在のOSは皆マルチタスクですからC言語の場合メモリ管理はプログラマがしっかりやらねばなりません。
    • good
    • 2
この回答へのお礼

ありがとうございます。
NULLとは文字列の最後に入っているやつですね、
絶対入れないといけないのですよね~?

お礼日時:2002/12/20 23:24

コンパイルは通りますが、実行時に発生するエラーですね。



配列を定義した大きさを超えて、データを書き込んでしまったり、
不正な値が入っている・あるいはアクセスしてはいけないアドレスが入っているポインタ変数を使って値を書き込んだりした時に発生します。
    • good
    • 1
この回答へのお礼

ありがとうございます。アドレス違反ですね、、、
よくみてみます。

お礼日時:2002/12/20 22:42

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qセグメンテーション違反

C言語を使用しています。

構造体に値をいれようとしたら、コンパイルは出来るのですが、実行時に
「セグメンテーション違反です (core dumped)」
となってしまい、それ以上行えません。

構造体と代入したい変数との型は、合っています。

いろいろ本などで見ましたが、何が原因かわからず困っています。
教えてください。
宜しくお願いします。

Aベストアンサー

OSは何でしょうか。コンパイラは何を使用していますか?
通常、デバッグオプションをつけて実行すると、異常の発生したソースの箇所で止まりますので、それが手がかりになります。またNo1の方が言われてますように、ソースが公開できるのであれば、ソースを提示するのが良いかと思います。

QC言語のプログラムが実行できません。

C言語のプログラムが実行できません。

コンパイルは出来るんですが、実行すると、「Segmentation fault」と表示されてしまいます。

これは何のエラーなんでしょうか?
基本的な事かもしれませんが、分かる方宜しくお願い致します。

Aベストアンサー

僕も何度も出したなぁ。

ひとくちにSegmentation faultといっても、それこそさまざまな要因があるので、
これだけで原因を突き止めるのは非常に難しいです。

コンパイルはあくまで文法としてみているだけであり、
処理の流れ、メモリ確保など、プログラムそのものを見ているわけではありません。
このエラーが出るのは文法などよりもっと上位の原因なのです。
たとえばですが。
長さ10の配列があったとして、11番目以降を参照したりすると、
そういうのが出たような気がします。

ですから、変数があれば、その内容をprintf文で逐一出していき、
変な値が入っていないとか、少しずつ直していくしかないと思います。

QC言語のポインターに関する警告

line[100]で
「1」が格納されていたら「a」
「2」が格納されていたら「b」
「3」が格納されていたら「c」
とout[100]に代入する関数を作りたいのですが
コンパイルすると関数の部分で
warning: assignment makes integer from pointer without a cast
という警告がでます。
ポインターは使っていないのですが、ポインターに関する警告が出ているようで困っています。
どこが悪いのかまったくわからなくて作業が完全に止まってしまいました。
解決法をおしえてください。お願いします。

/*宣言*/
int=i; /*main関数内のfor文で使用*/
char line[100], out[100];
void change(int);

/*関数*/
void change(int i)
  {
   if(line[i]=='1'){
    out[10]="a\0"
   }if(line[i]=='2'){
    out[10]="b\0";
   }if(line[i]=='3'){
    out[10]="c\0"
}
}

line[100]で
「1」が格納されていたら「a」
「2」が格納されていたら「b」
「3」が格納されていたら「c」
とout[100]に代入する関数を作りたいのですが
コンパイルすると関数の部分で
warning: assignment makes integer from pointer without a cast
という警告がでます。
ポインターは使っていないのですが、ポインターに関する警告が出ているようで困っています。
どこが悪いのかまったくわからなくて作業が完全に止まってしまいました。
解決法をおしえてください。お願いします。

/*宣言*/
int...続きを読む

Aベストアンサー

>    out[10]="a\0"
>    out[10]="b\0";
>    out[10]="c\0"

"a\0"や"b\0"や"c\0"は「charへのポインタ」ですよ。

out[10]は「char」ですから「記憶域が小さい整数(つまり、charに)に、ポインタを代入すると、値が失われるぞ」と警告が出ます。

void change(int i)
  {
   if(line[i]=='1'){
    out[10]='a';
   }if(line[i]=='2'){
    out[10]='b';
   }if(line[i]=='3'){
    out[10]='c';
}
}
または
void change(int i)
  {
   if(line[i]=='1'){
    out[10]=0x61; /* aのASCIIコード */
   }if(line[i]=='2'){
    out[10]=0x62; /* bのASCIIコード */
   }if(line[i]=='3'){
    out[10]=0x63; /* cのASCIIコード */
}
}
と書きましょう。

>    out[10]="a\0"
>    out[10]="b\0";
>    out[10]="c\0"

"a\0"や"b\0"や"c\0"は「charへのポインタ」ですよ。

out[10]は「char」ですから「記憶域が小さい整数(つまり、charに)に、ポインタを代入すると、値が失われるぞ」と警告が出ます。

void change(int i)
  {
   if(line[i]=='1'){
    out[10]='a';
   }if(line[i]=='2'){
    out[10]='b';
   }if(line[i]=='3'){
    out[10]='c';
}
}
または
void change(int i)
  {
   if(l...続きを読む

QC言語でセグメンテーションエラーの原因がわからず困っています。

こんにちは。いつもお世話になっております。

C言語なのですが、何故かプログラムを実行するとセグメンテーション違反が表示されてしまい全く動きません。皆さんのお力を貸して頂けないでしょうか。
以下が問題のプログラムです。
前提条件:
・別プログラムによりfile.txtは末尾に文章が追加され続けている
・本プログラムは永劫的に動き続ける

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<signal.h>
#include<sys/types.h>

int
main ()
{
int i = 1, a;
FILE *fp, *fp2;
char *tok;
//NULLを入れて初期化
char buf[1024] = "";
char str[1024] = "";
char str2[1024] = "";

//出力するファイルを開く
if ((fp2 = fopen ("out.txt", "a")) == NULL)
{
printf ("out.txt:open error\n");
exit (-1);
}

while (1)
{
//何度もfopenするのでループ二週目以降は一旦fpを閉じる
if (str2 != NULL)
{
fclose (fp);
}
//一度読み込み、2週目以降もさらに読み込み続ける
if ((fp = fopen ("file.txt", "r")) == NULL)
{
printf ("file.txt:open error\n");
exit (-1);
}
//str2はループ2週目以降で使われる
if (str2 != NULL)
{
while (1) //新しい行を見つけ出す
{
fgets (str, 1024, fp);
if (strstr (str, str2) != NULL)
{
printf ("前回の最終行です:%s\n", str);
break;
}
}
}
else
{

printf ("str2はNULLです:%s\n", str2);
}
//fopenで読み込んだ現段階のテキストファイルをout.txtに移す
while (1)
{
if( (fgets (str, 1024, fp) ) == NULL)break;

if ((a = strlen (str)) >= 2)
{
str[a - 1] = '\0';
}
else
{
printf ("抽出した文字列が1文字以下です:%s\n",
str);
break;
}
if (strlen (str) >= 17)
{
strcpy (str2, str);
}
else
{
printf ("抽出した文字列が16文字以下です:%s\n",
str);
break;
}

printf ("%s\n", buf);
fprintf (fp2, "%s\n", buf);
strcpy (buf, "");
strcpy (str2, str);


}

printf ("これが検索語です:%s\n", str2);

}

fclose (fp2);
return 0;
}

プログラムの内容は、
更新され続けるテキストファイル(file.txt)から、別のテキストファイル(out.txt)に出力するというプログラムです。(file.txtの内容を若干変えつつ、out.txtに出力することが本来の目的ですが、その部分は省略させて頂きました。)
fopenで開くと、「その時点まで」のfile.txtしか開かれません。更新され続けているfile.txtの内容をコンスタントに読み取る為に、while文でfopenし続ける方法を取っていますが、そうするとout.txtに移し終わった行まで読み込んでしまい重複した文章をout.txtに移すことになりますので、strstrを使い、「前回fopenで開いたfile.txt」の最終行を検索してその位置からまたout.txtに移す、という方法を取りました。しかし、結果は何故かセグメンテーション違反でした。

以上のプログラムや私の意図する所で何か気づかれた点や、おかしいと思われた点等ありましたら是非ご教授頂きたく思います。
どんな些細なことでも構いませんので、教えて頂けないでしょうか。
環境はCentosです。どうぞよろしくお願いします。

こんにちは。いつもお世話になっております。

C言語なのですが、何故かプログラムを実行するとセグメンテーション違反が表示されてしまい全く動きません。皆さんのお力を貸して頂けないでしょうか。
以下が問題のプログラムです。
前提条件:
・別プログラムによりfile.txtは末尾に文章が追加され続けている
・本プログラムは永劫的に動き続ける

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<signal.h>
#include<sys/types.h>

int...続きを読む

Aベストアンサー

とりあえず前半ざっと読んだ感じで……

・配列とポインタの違いがわかっていないように見える(NULLを入れて初期化、のコメント)
・str2はNULLにならないので最初から「二周目以降」のブロックに入ってしまう。segmentation faultの原因はこれにより開いていないfp2をfclose()しようとしているためと思われる
・「たまたま同じ行がある」場合の考慮がなされていない。元ファイルが追記以外の処理をしないなら、同値判定よりも読み込んだ回数を記憶しておいた方が簡単

Qセグメンテーション違反とは??

linuxでC言語のプログラムを構築しています。
gccでコンパイルしたときにセグメンテーション違反という
エラーが出てしまいます。
セグメンテーション違反とは一体なんの
ことなんでしょうか?
メモリのことだと思ってるんですが、原因がよくわかりません。C言語初心者なので
わかりやすく教えて頂けるとありがたいです。

Aベストアンサー

似たような質問を発見しました。以下のURLを参考にしてみてはどうでしょうか?

参考URL:http://oshiete1.goo.ne.jp/kotaeru.php3?q=715484

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

Qがあるのにsqrtが・・・

最初にあるプログラムを作っていたのですが、その祭sqrtでエラーが出てしまったので、別にsqrtを使う短いプログラムを作りました。それが以下のものになります。(test3.c)

#include<stdio.h>
#include<math.h>

int main(void){
int atai;
double x=2.0;
atai=(int)sqrt(x);
printf("atai is %c",atai);
}


sqrtが動作するか確かめる為のものです。このプログラム(test3.c)で以下のエラーが出てしまいました。

/tmp/ccqEejZ1.o(.text+0x4d): In function `main':
test3.c: undefined reference to `sqrt'
collect2: ld はステータス 1 で終了しました

ちなみにLinux(Fedora core 4)を使用しています。
初心者ということもありなぜエラーが出るのか分かりません。
ちなみに<math.h>を使用しないプログラムは普通に動作します。
解決方法をご存知の方がいらっしゃいましたらご教授下さいませ。
よろしくお願いします。

最初にあるプログラムを作っていたのですが、その祭sqrtでエラーが出てしまったので、別にsqrtを使う短いプログラムを作りました。それが以下のものになります。(test3.c)

#include<stdio.h>
#include<math.h>

int main(void){
int atai;
double x=2.0;
atai=(int)sqrt(x);
printf("atai is %c",atai);
}


sqrtが動作するか確かめる為のものです。このプログラム(test3.c)で以下のエラーが出てしまいました。

/tmp/ccqEejZ1.o(.text+0x4d): In function `main':
test3.c: undefined r...続きを読む

Aベストアンサー

コンパイルのオプションつけてないとかないですよね?
たとえばTerminalとかだとコンパイル時に 『-lm』とかつけますが

Qfgetsで拾われる改行文字を削除したい

お世話になります

 C言語初心者のものです。今課題でC言語を用いたプログラミングを
Fedora上でやっています。問題は、fgetsでテキストファイルから、取得
した文字列の中から改行文字を削除できないことです。文字変数のアド
レスはわかっているのですが、終端文字に置換しようとすると、セグメ
ントエラーになってしまいます。これは如何にして解決すべきでしょう
か。よろしくお願いします。

Aベストアンサー

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが最大文字数に達したり、ファイルの最後になったりで、strに改行文字が含まれない場合には、このループは止まりません(Segmentension Falutになって止まる)

・そのような状態になってないか、予めチェックする
・ループを終了させる仕組みを用意しておく
: forの終了条件を記述する、for中で if(*(str+i)=='\0') { break;} 等としておく、等
といった対策が必要です。


あと細かいところを言えば
・strを配列で用意したなら *(s+i)じゃなくてs[i]でいいんじゃないかな
・あるいは char *pみたいにしておいて、 iのループでなく pでループを組む( for(p=str;*p!='\0';p++) )とか。

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが...続きを読む

QC言語 配列の長さの上限

C言語で配列Array[N]の長さNの上限っていくらなんでしょうか?
もし可能なのであれば上限を2147483647にしたいのですが、方法を教えてください。

Aベストアンサー

そもそもWindowsの32bit版はアプリが仮想メモリ空間を2GBしか使えません。2GBを超えるには64bit版が必要です。
たとえ64bit版OSだとしても添え字が2147483647って、単純なintの配列だとしても4x2147483647=8GB必要ですね。実メモリ16GBとかのPCを用意しますか?
そもそも配列で2147483647個必要なアルゴリズムに問題ありだと思います。

Q構造体の各データの表示について以下のようなプログラムを作成しました。

構造体の各データの表示について以下のようなプログラムを作成しました。

#include <stdio.h>

struct tb{
char name[20];
char sex;
int age;
double height;
double weight;
};

int main(void)
{
int i;

struct tb test[2];

test[0].name="amada"
test[0].sex='f';
test[0].age=20;
test[0].height=172.5;
test[0].weight=62.5;

test[1].name="okada";
test[1].sex='f';
test[1].age=21;
test[1].height=180.2;
test[1].weight=70.8;

for(i=0; i<2; i++){
printf("%s %s %d %f %f \n",test[i].name,test[i].sex,test[i].age,test[i].height,test[i].weight);
}

return 0;
}

ファイル名を適当にsample.cとしてgcc sample.c した所、以下のようなコンパイルエラーが出ました。

sample.c: In function ‘main’:
sample.c:18: error: incompatible types when assigning to type ‘char[20]’ from type ‘char *’
sample.c:18: error: expected ‘;’ before ‘test’
sample.c:23: error: incompatible types when assigning to type ‘char[20]’ from type ‘char *’

このエラーを元にソースをどのように修正したらよいか教えて頂けますでしょうか?
よろしくお願いいたします。

構造体の各データの表示について以下のようなプログラムを作成しました。

#include <stdio.h>

struct tb{
char name[20];
char sex;
int age;
double height;
double weight;
};

int main(void)
{
int i;

struct tb test[2];

test[0].name="amada"
test[0].sex='f';
test[0].age=20;
test[0].height=172.5;
test[0].weight=62.5;

test[1].name="okada";
test[1].sex='f';
test[1].age=21;
test[1].height=180.2;
test[1].weight=70.8;...続きを読む

Aベストアンサー

エラーメッセージに書いてある通り
構造体を以下のように定義するか
struct tb{
char name[20]; -> char *name
char sex;
int age;
double height;
double weight;
};

#include <string.h>
を追加して
strcpy(test[0].name,"amada");
にするかのいずれか(後者の方がいいと思うけどね)

あとは
>test[0].name="amada"
文末に;が無いね。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング