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

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

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

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

Q&A

解決済

4回答

6340閲覧

staticを付けないとコアダンプ

cingyan

総合スコア29

C

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

0グッド

0クリップ

投稿2017/09/22 15:08

ネット上で見つけたコードに変更を加えて実行するとコアダンプになるので、原因を教えてください。
プログラムはファイル内の文字列の変更です。
コードは以下になります。

#include <stdio.h> #include <string.h> int main(void) { FILE *fp,*fo; int a; char *search = "FLG=0"; //←検索前の文字列 char *string = "FLG=1"; //←置換後の文字列 char *buff,*seek,*find; char one[256]; fp = fopen("test.txt","r"); fo = fopen("test1.txt","w"); while ( fgets(buff,sizeof(buff),fp) != NULL ){ for ( seek = buff ; (find = strstr(seek,search)) != NULL ; seek = find ){ a=(find-seek); fprintf( fo, "%.*s",a ,seek ); fputs( string, fo ); find += strlen( search ); } if ( find == NULL ){ fputs( seek, fo ); } } fclose(fp); fclose(fo); return 0; }

これを実行すると、「 Segmentation fault (コアダンプ) 」
と表示されて実行できません。

10行目の

char one[256];

static char one[256];

とすると実行できます。

どうして失敗したり成功したりするのか教えてください。

パソコンは ubuntu コンパイラは gccです。

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

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

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

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

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

guest

回答4

0

こんにちは。

oneをstaticにするかどうかで変化するのはたまたまです。

fgets(buff,sizeof(buff),fp)

でbuffへ読み込んでいるつもりと思いますが、不適切です。
buffはchar型へのポインタですが、初期化していませんので、あらぬメモリを指しています。そこに何があるか分かりませんのでメモリを破壊します。
運が悪ければ継続して動作しますし、運が良ければ落ちます。(メモリを破壊しつつ動作継続するのは本当に怖いので、落ちないのは運が「悪い」です。)

投稿2017/09/22 15:29

Chironian

総合スコア23272

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

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

cingyan

2017/09/23 07:28

char *buf=one; と初期化するとできました。 ありがとうございました。
guest

0

static を付けると大丈夫かどうかは言わば結果論で、原因はそこではなさそうです。

恐らくfgets()を呼び出した時点でSegmentation fault で落ちています。
fgets() で使用している変数buffはchar*のポインターで宣言していて、
しかも初期化していません。ポインターの値として不正になっている可能性大です。

バッファー/領域として使用するつもりのbuffと、位置を参照する為のポインターの意識が
混在しているようです。その辺の整理を先にすることをお薦めします。

投稿2017/09/22 15:22

dodox86

総合スコア9183

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

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

cingyan

2017/09/23 07:29

仰る通りです。 配列で領域確保ですね。 ありがとうございました。
guest

0

ベストアンサー

どこかにバッファ領域を取ってbufがそれを指すように初期化しないといけません。
あとsizeof(buf)もこのままだとバッファサイズではなく ポインタのサイズになります。

一番修正が少ないのは
char *buf

char buf[10240]
とかに変えることかな。バッファサイズがいくつが適切かは処理するデータによります。

投稿2017/09/22 22:52

a_saitoh

総合スコア702

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

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

cingyan

2017/09/23 07:16

回答ありがとうございました。 仰る通りです。コードをコピペして検証していませんでした。 配列にすると成功しました。
guest

0

そもそも変数oneは定義されているだけで使用されておりません。この変数によってプログラムに影響が出るならば「動作未定義」の状態になっている可能性があります。

以下、参考情報(C言語の規格で定められているものではないです)
ちなみにstaticを付けた場合、ヒープ領域にメモリ確保される傾向にあります。(通常はスタック領域)例えば、スタック領域がヒープよりも小さい場合、staticを付けるだけで挙動が変わるということはありえます。繰り返しますが、C言語の規格ではなく、「傾向が強い」というだけです。

投稿2017/09/22 15:21

HogeAnimalLover

総合スコア4830

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

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

cingyan

2017/09/23 07:38

fclose(fp); fclose(fo); fgets(one,256,stdin); remove("test.txt"); fgets(one,256,stdin); rename("test1.txt","test.txt"); return 0; } コードの終わりにこのようにしていたのですが、これをコメントアウトしても $ ./a.out Segmentation fault (コアダンプ) となるので、省略していました。 勉強になりました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問