マルシェル新規登録で5000円分当たる

こんにちわ,
現在プログラムを作成しているのですが,Segmentation Faultが出て困っています。

そのセグメント違反が出ているのがmallocの中(PCインナーの関数)で普通ならmallocの返り値がNULLかそれ以外かということになりますが,それ自体も中でセグメント違反が起こるので帰ってきません。

MALLOC_CHECK_=1によってその触っているポインターを見ると,
free(): invalid pointer 0x93c5380!
free(): invalid pointer 0x93c5c18!
とでるので,おそらくmallocのなかで必要なくなったポインターをフリーをしていると考えられるのですが,
gdbのwatchpointでそのアドレスを指定してみてみると,メインに入る前にそのポインタ自体をいじっている関数も内部的な関数みたいでどこをなおすとセグメント違反が直るのかわかりません。

このようなメモリ問題がおきたときどのようなツールや解決法があるのでしょうか。

よろしくお願いします。

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

A 回答 (4件)

> このようなメモリ問題がおきたときどのようなツールや解決法があるのでしょうか。



このようなメモリ問題は起こしてはいけません。いや、冗談ではなく、本当に。
プログラムの、全然関係の無い場所で破壊が起きていたら、突き止めるのは非常に
困難です。追跡するとしたら、malloc()とfree()の呼び出しの都度、その情報を
吐き出して、後で対照させてみるといったところでしょうか。

重要なのは予防です。とりあえず、心がけることとしては、
・グローバル変数を多用しない。特に、ポインタはグローバル変数にしない。
・自動変数(内部変数)のアドレスを外部に持ち出さない。
・free()したポインタ変数は、すぐにNULLで初期化しておく。
あたりでしょうか。

すみません。ツールはあるかもしれませんが、知りません。
    • good
    • 0

ParaSoft社からInsure++がでています。


以下は、Insure++の概要です。
------------------------------------
Insure++は、C/C++アプリケーションのランタイムエラーを自動的に検出する開発支援ツールです。メモリ破壊、メモリリーク、ポインターエラー、I/Oエラーといっ たC/C++特有の検出困難なエラーをプログラムコンパイル時と実行時に自動的に検出し、ファイル名、行番号、ソースコードなど、プログラムの修正に役立つ情報を的確にレポートします。また、そのレポートからソースコードにジャンプし、その場でエラーを修正することも可能です。さらに、TCAやInuseを使用することにより、カバレッジ分析、メモリ使用分析も可能です。Insure++を使用することにより、高品質なソフトウェアを迅速かつ容易に開発できます。
-------------------------------------------
私は、これを使用した経験はありませんので、今回の問題の解決に有効であるとは、言い切れませんが、試してみる価値はあると思います。
現在 LINUX用の体験版(20日間有効)が無償で提供されていますので、それを利用されてはいかがでしょうか。

参考URL:https://www.techmatrix.co.jp/asq/insure/index.html
    • good
    • 0

#1さんや#2さんが仰るように、メモリ周りを壊すとタチが悪い


挙動になってしまいます。

一撃でトドメを刺してくれるようなメモリ破壊なら一目瞭然ですが、
ボディーブローのように内面を静かに壊して行くパターンも多々有り
厄介です。
後者の場合、全然関係無いタイミングで落ちます。多いのは関数から
リーターンする等スタックが動くタイミングですが、正しいポインタ
の free や realloc 等の「それらしい」場所で反応する場合も有る
から始末に悪いです。

先に答えた方の復唱になってしまいますが、取り敢えず free して
いる箇所を全て

free(ptr);

  ↓

if (ptr != NULL) {
  free(ptr);
  ptr = NULL;
}

に置き換えてみて下さい。
変数 ptr 定義部での初期化もお忘れ無く。
例えば
char *ptr = NULL;

これで2重 free の罠からは脱出できます。
    • good
    • 0

そういう場合は、大抵他のところに問題があります。


一番考えられるのはメモリの二重 free です。
次に考えられるのはメモリ破壊です。
確保した領域を前か後ろにはみ出して使用していることが考えられます。
その観点でプログラムをチェックしてみてください。
    • good
    • 0

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

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

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

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

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

QC言語のデバック 領域の二重解放が原因か??

学生で流体力学の研究を行っています。
研究の一環でフリーの数値解析ソフトを使っているのですが、ポスト処理の機能が弱いので、自作してみようと思いC言語で書いてみました。実行したところ、何とか結果は得られるのですが、エラーが出てしまいます。原因を教えて頂けたら幸いです。

翼周りの圧力分布を計算しており、ある点での圧力が時間とともにどのように変化するのか知りたかったので、今回のプログラムを作成しました。
実行ディレクトリ内には各時刻(以下のプログラム内では t)のディレクトリが存在し、その中に圧力(p)のデータが存在しています。各時刻のある点の圧力を一つのファイルに出力したかったので以下のプログラムを作りました。
実行したところ、
*** glibc detected *** ./a.out: double free or corruption (out): 0x0896f008 ***
======= Memory map: =========
・・・
というエラーが出てしまします。glibc detectedは領域の二重解放を意味するらしいのですが、どこがおかしいのかわかりません。どなたか教えて頂けないでしょうか?
C言語はかじった程度の知識しかないので、ほかにも変な点などがありましたら指摘して欲しいです。ubuntu 10.4上で動かしています。


実行ディレクトリ内   [以下のプログラム 0.0001 0.0002 0.0003 0.0004 ]
0.0001内        [p u(速度) などなど]
0.0002内   [p u(速度) などなど]
・・・


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

/* ベクトルの入力 */
void input_vector2(double *b, double t,int i , FILE *fin, FILE *fout);
/* 行列の領域確保 */
double **dmatrix(int nr1, int nr2, int nl1, int nl2);
/* 行列の領域解放 */
void free_dmatrix(double **a, int nr1, int nr2, int nl1, int nl2);
/* ベクトル領域の確保 */
double *dvector(int i, int j);
/* ベクトル領域の解放 */
void free_dvector(double *a, int i);

int main(void)
{
FILE *fin, *fout;
double *x;
double t1,t2,dt,t;
int n,i;
char fn[5];/*圧力を指定するためのパス*/
t1 = 0.0001; /* 初期時刻 */
t2 = 0.0004; /* 終了時刻 */
dt = 0.0001; /*時間幅*/


n = 1 + (t2-t1)/dt; /* データ数 */

/* ベクトルの領域確保 */
x = dvector(1,n); /* x[1...n] */

/*書き込み用ファイルのオープン*/
if( (fout = fopen( "output_p.dat", "w")) == NULL )
{
printf("ファイルが作成できません : output_p.dat \n");
exit(1);
}

for( i = 0 ; i <= n ; i++)
{
t=t1+dt*i;

sprintf( fn,"./%5.4f/p",t);
/* ファイルのオープン */
if( (fin = fopen( fn , "r")) == NULL )
{
printf("ファイルが見つかりません : fn/p.dat \n");
printf("%s \n",fn);
exit(1);
}


input_vector2( x, t, i,fin, fout ); /* ベクトルxの入出力 */
fclose(fin); /* ファイルのクローズ */

}
fclose(fout); /* ファイルのクローズ */

/* 領域の解放 */
free_dvector( x, 1 );
return 0;
}


/* b[1...n]の入力 */
void input_vector2( double *b, double t,int i ,FILE *fin, FILE *fout)
{
double a;
fseek(fin,860,SEEK_SET);
fscanf(fin, "%lf", &b[i]);
fprintf(fout, "%5.4f\t",t);
fprintf(fout, "%5.2f\n", b[i]);


}

double **dmatrix(int nr1, int nr2, int nl1, int nl2)
{
int i, nrow, ncol;
double **a;

nrow = nr2 - nr1 + 1 ; /* 行の数 */
ncol = nl2 - nl1 + 1 ; /* 列の数 */

/* 行の確保 */
if ( ( a=(double **)malloc( nrow*sizeof(double *) ) ) == NULL )
{
printf("メモリが確保できません(行列a)\n");
exit(1);
}
a = a - nr1; /* 行をずらす */
/* 列の確保 */
for( i=nr1; i<=nr2; i++) a[i] = (double *)malloc(ncol*sizeof(double));
for( i=nr1; i<=nr2; i++) a[i] = a[i]-nl1; /* 列をずらす */

return(a);
}

void free_dmatrix(double **a, int nr1, int nr2, int nl1, int nl2)
{
int i;

/* メモリの解放 */
for ( i = nr1 ; i <= nr2 ; i++) free((void *)(a[i]+nl1));
free((void *)(a+nr1));
}


double *dvector(int i, int j) /* a[i]?a[i+j]の領域を確保 */
{
double *a;

if ( (a=(double *)malloc( ((j-i+1)*sizeof(double))) ) == NULL )
{
printf("メモリが確保できません(from dvector) \n");
exit(1);
}

return(a-i);
}

void free_dvector(double *a, int i)
{
free( (void *)(a + i) ); /* (void *)型へのキャストが必要 */
}

学生で流体力学の研究を行っています。
研究の一環でフリーの数値解析ソフトを使っているのですが、ポスト処理の機能が弱いので、自作してみようと思いC言語で書いてみました。実行したところ、何とか結果は得られるのですが、エラーが出てしまいます。原因を教えて頂けたら幸いです。

翼周りの圧力分布を計算しており、ある点での圧力が時間とともにどのように変化するのか知りたかったので、今回のプログラムを作成しました。
実行ディレクトリ内には各時刻(以下のプログラム内では t)のディレクトリが存在し...続きを読む

Aベストアンサー

/* ベクトルの領域確保 */
x = dvector(1,n); /* x[1...n] */

ここのコメントと、dvector の関数の実装は一致しています。
でも、

for( i = 0 ; i <= n ; i++)
{
 …
input_vector2( x, t, i,fin, fout ); /* ベクトルxの入出力 */
 …
}

と、iが0からnまで動くのに input_vector2関数内で、

void input_vector2( double *b, double t,int i ,FILE *fin, FILE *fout)
{
 …
 fscanf(fin, "%lf", &b[i]);
 …
}

と x[0...n] に対して代入が行われることになるのは、どうなのでしょうか?

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

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

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

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

Aベストアンサー

僕も何度も出したなぁ。

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

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

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

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

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

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

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

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

Aベストアンサー

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

Qint型からchar型への変換

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

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

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

Qreallocでエラー

reallocを使うとエラーがでます。
簡単なreallocのプログラムでもエラーがでて、realloc自体が使えないような感じです。
どうしたらよいでしょうか?
試したプログラムは

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int main(void){
char *p;
p=malloc(17);
if(!p){
printf("error\n");
exit(1);
}
strcpy(p,"これは16文字です");
p=realloc(p,18);
if(!p){
printf("error\n");
exit(1);
}
strcat(p,".");
printf(p);
free(p);
return 0;
}

というもので、

*** glibc detected *** ./test: realloc(): invalid next size: 0x09b61008 ***
======= Backtrace: =========
/lib/libc.so.6[0x43ca2f]
/lib/libc.so.6(realloc+0xfe)[0x43e68e]
/lib/libc.so.6[0x43ea61]
/lib/libc.so.6(realloc+0x3c)[0x43e5cc]
./test[0x8048512]
/lib/libc.so.6(__libc_start_main+0xe0)[0x3e8f70]
./test[0x80483e1]
======= Memory map: ========
00235000-0023f000 r-xp 00000000 fd:00 360450 /lib/libgcc_s-4.1.2-20070626.so.1
0023f000-00240000 rwxp 00009000 fd:00 360450 /lib/libgcc_s-4.1.2-20070626.so.1
003d3000-00521000 r-xp 00000000 fd:00 360473 /lib/libc-2.6.so
00521000-00522000 r-xp 0014e000 fd:00 360473 /lib/libc-2.6.so
00522000-00524000 rwxp 0014f000 fd:00 360473 /lib/libc-2.6.so
00524000-00527000 rwxp 00524000 00:00 0
00616000-00631000 r-xp 00000000 fd:00 360466 /lib/ld-2.6.so
00631000-00632000 r-xp 0001a000 fd:00 360466 /lib/ld-2.6.so
00632000-00633000 rwxp 0001b000 fd:00 360466 /lib/ld-2.6.so
006c0000-006c1000 r-xp 006c0000 00:00 0 [vdso]
08048000-08049000 r-xp 00000000 fd:00 3473718 /home/gucchi/test/test
08049000-0804a000 rw-p 00000000 fd:00 3473718 /home/gucchi/test/test
09b61000-09b82000 rw-p 09b61000 00:00 0
b7e00000-b7e21000 rw-p b7e00000 00:00 0
b7e21000-b7f00000 ---p b7e21000 00:00 0
b7fd6000-b7fd8000 rw-p b7fd6000 00:00 0
bfb07000-bfb1c000 rw-p bfb07000 00:00 0 [stack]
アボートしました

というエラーがでます。
試しに他の環境でコンパイルしたら実行できちゃいました。
glibcに問題があったりするんでしょうか?
ご教授ください。

reallocを使うとエラーがでます。
簡単なreallocのプログラムでもエラーがでて、realloc自体が使えないような感じです。
どうしたらよいでしょうか?
試したプログラムは

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int main(void){
char *p;
p=malloc(17);
if(!p){
printf("error\n");
exit(1);
}
strcpy(p,"これは16文字です");
p=realloc(p,18);
if(!p){
printf("error\n");
exit(1);
}
strcat(p,".");
printf(p);
free(p);
...続きを読む

Aベストアンサー

次のプログラムの結果はどうなりますか?
#include <stdio.h>
int main()
{
static const char msg[] = "これは16文字です";
printf("%zu\n", sizeof msg);
return 0;
}

Qメモリの再確保について

テキストファイルを読込む関数を作成しています。
まず最初にある程度の領域をmalloc()関数で確保し、
読み込む過程で領域が不足すると再割り当てを
行うようにしたいのですが、
エラーが出力されます。
ソース(エラー処理は省略)は次の通りです。

textdata = (char *) malloc (size * sizeof (char));

for (i = 0; !feof (stream); ) {
character = fgetc (stream);
textdata[i] = character;
i++;

if ((i % size) == 0) {
temp = (char *) malloc (2 * size * sizeof (char));
memcpy (temp, textdata, size * sizeof (char));
free (textdata);
textdata = temp;
}
}

出力されるエラーは次の通りです。

*** glibc detected *** ./lsm: malloc(): memory corruption (fast): 0x09a34198 ***
(省略)
アボートしました

どなたか解決方法を御指導願います。

テキストファイルを読込む関数を作成しています。
まず最初にある程度の領域をmalloc()関数で確保し、
読み込む過程で領域が不足すると再割り当てを
行うようにしたいのですが、
エラーが出力されます。
ソース(エラー処理は省略)は次の通りです。

textdata = (char *) malloc (size * sizeof (char));

for (i = 0; !feof (stream); ) {
character = fgetc (stream);
textdata[i] = character;
i++;

if ((i % size) == 0) {
temp = (char *) malloc (2 * size * sizeof...続きを読む

Aベストアンサー

memcpy以降でsizeを二倍してください。
いまのままだと、常にsizeの初期値*2のメモリしか確保されませんので、sizeの初期値*2以上読み込もうとするとメモリ破壊が起きてしまいます。

QSegmentation Fault (メモリ制限?)

Segmentation Fault (Fortranのプログラム)に関して質問です。


あるデータを処理するプログラムですが、小さなデータの場合問題ないですが、
大きなデータを扱うようになった場合Segmentation Faultとなります。

宣言している配列サイズを超えた部分のアクセスなどでSegmentation
Faultが出ることがあるようですが、どうやらそのような現象ではなく、
メモリ制限にひっかかっている感じがいたします。


エラーが出る部分はどうやらSubroutine内の大きなデータ宣言を
している部分のようです。(下の例ではtest bが表示れる以前に止まります。)

!--------------------------------------------------
subroutine calc_tri( )

implicit none

real*8 data1(3,200000) !<--- ここでエラー -->

write(6,*) 'test b'
!--------------------------------------------------


このような場合、配列データを減らす以外にどのような対策が
あるのでしょうか?
あるいはメモリ制限になりそうなデータ数が分る方法などあります
でしょうか?


環境は
linux (CentOS)
intel Fortran Compiler version 8.0
Mem: 1GB

topコマンドにて Memの使用割り合いは10%にもならないのですが
コンパイラによるメモリ制限などもあるのでしょうか?

subroutine内の配列の宣言はデータ数より多くとっていることは確認しています。

Segmentation Fault (Fortranのプログラム)に関して質問です。


あるデータを処理するプログラムですが、小さなデータの場合問題ないですが、
大きなデータを扱うようになった場合Segmentation Faultとなります。

宣言している配列サイズを超えた部分のアクセスなどでSegmentation
Faultが出ることがあるようですが、どうやらそのような現象ではなく、
メモリ制限にひっかかっている感じがいたします。


エラーが出る部分はどうやらSubroutine内の大きなデータ宣言を
している部分のようです。(下...続きを読む

Aベストアンサー

スタックオーバフローを起こしているのでは。
ulimitとかでスタックサイズを引き上げるか、ALLOCATABLEな配列にしてヒープ領域を使うようにするとか。

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が...続きを読む

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

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

Aベストアンサー

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

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

QLinuxのgccのインクルードパス?

Linuxのgccで、インクルードファイルやライブラリのパスを設定する方法が知りたいのですが、gccについて詳しい書籍やサイトがありましたら、教えてください。

gccとccの違いも知りたいです。

例)
#include "example.h"

このままだと、example.hが無いと表示されます。

Aベストアンサー

標準ライブラリのパスは、gccのインストール時に指定して、Cプリプロセッサの中に組み込まれます。

#include "example.h"
は、まずカレントディレクトリを探し、次に gccコマンドラインの -I オプションで指定したディレクトリを探し、最後に標準ライブラリが探されます。

#include <example.h>
は、カレントディレクトリを探さない点が異なります。

ccも基本的には同じですが、Unixの種類によって機能が異なる可能性があります。Linuxの場合はcc=gccです。


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

人気Q&Aランキング