new/deleteで異常終了する(Visual C++)
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2010/01/06(水) 20:35:52Visual C++ 2008でコーディングしています。
コーディングは何度も何度も見直しました。
間違っていません。
なのに、実行するとnewで異常終了します。
debug版で動かすと動きます。release版で動かすと異常終了します。
デバッグのしようがありません。
ホントに、コーディングは正しいんです。
こういう症状の原因って何が考えられるでしょうか。
よろしくお願いします。
deleteでも異常終了します。
未初期化ポインタのdeleteとかそんなのではなくて、
本当にコーディングはあってるのに、異常終了します。
動きは、毎回違います。
例えば、printfデバッグをしようとしてprintfを
挿入すると、異常終了ポイントが変わります。
でも、newかdeleteで落ちます。
ホントに、ホントに、コーディングは合ってるのに
どうしようもありません。
もう何ヶ月も仕事が進みません。
このままだと、クビになっちゃいます。
お願いします、本当に、よろしくお願いします。
0002デフォルトの名無しさん
2010/01/06(水) 20:43:530003デフォルトの名無しさん
2010/01/06(水) 20:55:46ローカルルールを見直せ
0004デフォルトの名無しさん
2010/01/06(水) 21:08:290005デフォルトの名無しさん
2010/01/06(水) 21:18:13言語訓練のために立てたものです。
アイと研究員とのやり取りに利用するスレッドなので、
関係者以外は書きこまないで下さい。
京都大学霊長類研究所
0006デフォルトの名無しさん
2010/01/06(水) 21:23:08これってdelete文を全部コメントアウトしても症状は同じ?
一再deleteしなくても一応は動くでしょ。deleteしないとメモリーオーバフローしちゃう?
0007デフォルトの名無しさん
2010/01/06(水) 21:56:280008デフォルトの名無しさん
2010/01/06(水) 22:00:390009デフォルトの名無しさん
2010/01/06(水) 22:10:080010デフォルトの名無しさん
2010/01/06(水) 22:11:240011デフォルトの名無しさん
2010/01/06(水) 22:12:04単発の質問でスレ立てはマナー違反な。
いちおう言っとくけど。
0012デフォルトの名無しさん
2010/01/06(水) 22:12:540013デフォルトの名無しさん
2010/01/06(水) 22:13:0900141
2010/01/06(水) 22:39:52下記のような感じなんです。
class C1 {
private:
// メンバ
int *a ; int *b ; C2 *c ; // C2はクラスね
public:
// コンストラクタ
C1( void ) { a = NULL ; b = NULL ; c = NULL ; return ; } ;
// デストラクタ
~C1( void ) { delete [] a ; delete [] b ; delete [] c ; return ; } ;
public:
// 初期化メソッド
int init( void ) {
a = new int[ 5 ] ; b = new int[ 5 ] ; c = new C2[ 5 ] ;
if ( !a || !b || !c ) {
delete [] a ; delete [] b ; delete [] c ;
a = NULL ; b = NULL ; c = NULL ;
return -1 ;
}
return 0 ;
} ;
public:
// 各種メソッド
int xxx( xxx ) { xxx ; } ;
} ;
00151
2010/01/06(水) 22:41:54い。 コンストラクタでNULLを入れる。
ろ。 init()で領域確保。
は。 失敗したらNULLを入れる。
に。 deleteしたらNULLを入れる。
ほ。 デストラクタで開放する。
は、徹底してます。
上記、C2の例みたく、デストラクタが
どんどん直列に呼び出される場合があります。
00161
2010/01/06(水) 22:43:06いま、家なので、明日会社でやってみます。
もし仮にdeleteしないでうまくいったら、
deleteが原因ってことですか?
> 7
何が破壊されていますか。
破壊のよくある失敗原因はありますか。
> 11
ごめんなさい。しりませんでした。次から気をつけます。
でも、ネットで調べても全然のってないんです。
もう、2chにアクセスするエリートプログラマしか
頼れないんです。
> 12
えっ、そんな方法あるんですか。
明日会社でトライしてみます。
0017デフォルトの名無しさん
2010/01/06(水) 22:44:37んー、特に問題は見あたらないなー
0018デフォルトの名無しさん
2010/01/06(水) 23:07:37もし、deleteを外して直るなら、同じポインタを2回deleteしてる可能性があるね。
>>14 を見るかぎり大丈夫そうだけど。
まあ、簡単に外せるなら1回外してみるのが早いけどね。
関係ないと思うけど、// 初期化メソッド でa b cのどれかがNULLだったらa b c ともdeleteしてるけど
これおかしくない? NULLポインタをdeleteする事になちゃうよ。
if ( !a || !b || !c ) {
if( a ) delete [] a;
if( b ) delete [] b;
if( c ) delete [] c;
a = NULL; b = NULL; c = NULL;
return -1;
}
return 0;
にしないと。まあ、new が失敗するなんて殆んど考えられないけどね。
0019デフォルトの名無しさん
2010/01/06(水) 23:13:180020デフォルトの名無しさん
2010/01/06(水) 23:14:040021デフォルトの名無しさん
2010/01/06(水) 23:22:46これはスマン。NULLポインタにdeleteしたことなんか無かったもんで。
0022デフォルトの名無しさん
2010/01/06(水) 23:34:140023デフォルトの名無しさん
2010/01/07(木) 00:13:19俺の感で言うと暗黙のoperator=でポインタをコピーして二重deleteとみた。
0024デフォルトの名無しさん
2010/01/07(木) 00:14:28ぼくわるくないもん! ぼくわるくないもん! ぼくわるくないもん! ぼくわるくないもん!
> なのに、実行するとnewで異常終了します。
わるいのはかんきょうだ! ぼくわるくないもん!
って時点でもうね。
ガチで書いているなら向いていないから辞めなさい。社会人を。
ネタで書いているなら向いていないから辞めなさい。人間を。
0025デフォルトの名無しさん
2010/01/07(木) 00:17:12正直初心者がC++とかやると周りが不幸になるからやめたほうがいいよなー。
>>24
俺はC++で間違いなく書けたなんてRAII徹底しないと自信を持てないな。
生のポインタ使いつつ自信を持てる人をある意味、尊敬する。ある意味な。
0026デフォルトの名無しさん
2010/01/07(木) 00:21:54調べるのが定石
0027デフォルトの名無しさん
2010/01/07(木) 00:40:55一応、古い処理系だとnew失敗でnullが返る(std::nothrowなしでも)のはあるが…
自分はVS2008は使わんので分からないが、どっちなのだろうか?
>>25
烈しく同意。自分はC++に限らず「間違っていない」なんて口が割けても絶対に言えんわ。
0028デフォルトの名無しさん
2010/01/07(木) 01:05:45このパターンだと、多分それだと捕まらないんじゃないかなぁ。
> 動きは、毎回違います。
ってことだから。
アホの書いたコードがビルドやprintfデバッグで挙動が変わる場合、高確率でメモリ破壊やメモリ未初期化が原因。
それにより、バイナリが変わる度にヒープやスタック(やそこに残ったゴミ)の状況が変化し現象が変化する。
そしてほぼ全てのアホは、根拠皆無なのに何故か肥大化したプライドを守るために
目が曇って and/or 意図的に目を曇らせ、いくらコードを見てもそれを発見できずに自分以外の何かが原因だと喚く。
> このままだと、クビになっちゃいます。
それはヤバいね。先手を打って自分から退職願を出せば自分都合になるし退職金ももらえるよ?
0029デフォルトの名無しさん
2010/01/07(木) 01:11:47Visual C++ 6.0がNULLを返す最後の世代。
2008は9.0だから(数ヵ月後には2010(10.0)が出る)
普通のnewでNULLが帰ってくるのは現在考慮する必要は殆どないかと。
# 昔からのコードの保守で使わざるを得ない不幸な環境の人も多少はいるでしょうが
0030デフォルトの名無しさん
2010/01/07(木) 01:40:16メモリ無くなったらNULL参照で落ちるという糞処理系
まあ例外投げるようにすることはできるから
そうすりゃいいだけの話ではあるが
0031デフォルトの名無しさん
2010/01/07(木) 02:48:05コンパイルが通るかどうか
0032デフォルトの名無しさん
2010/01/07(木) 03:33:10C++じゃなくC#或はJavaで書いてみる。
十分本質的なコードが出来た後にC++に移植する。
プログラムに課せられている問題と、C++特有の
技術上の問題がごっちゃになると難しい。(特に
VCは細かい技術上の配慮が必要で繊細)
(いきなりC++で完璧なコードを作ること自体に無
理がありそう。それなりにCやC#,Javaの経験があっ
たほうがいい)
C++コード書けるんだったらJava,C#の
コードを書くのはそれほど難しくは無い。
ただライブラリ関数の名前を覚えたり
調べたりするのがちょっと最初はきついかも
0033デフォルトの名無しさん
2010/01/07(木) 04:04:280034デフォルトの名無しさん
2010/01/07(木) 04:17:41良い。精神衛生上問題が大有りだから。
仕様書がある限り、潔くそのコードを捨てて
書き直すのが最善。
JavaやC#とかのようなものでもそれが言える
C++だったら尚更。
0035デフォルトの名無しさん
2010/01/07(木) 04:20:11急がば回れ
でつねw
0036デフォルトの名無しさん
2010/01/07(木) 05:06:19>>14のコードじゃバグるのわかるだろ
0037デフォルトの名無しさん
2010/01/07(木) 05:11:22?
0038デフォルトの名無しさん
2010/01/07(木) 05:20:48class c;
と
class[] c;
を混同しようものならコンパイルが通らないから
そういった系統のバグは発生しない点では初学者には優しいか...
0039デフォルトの名無しさん
2010/01/07(木) 06:06:55new C2[5] とかしないで std::vector<C2> を使う
添え字の範囲もチェックする
0040デフォルトの名無しさん
2010/01/07(木) 07:31:380041デフォルトの名無しさん
2010/01/07(木) 17:05:030042デフォルトの名無しさん
2010/01/07(木) 20:48:08>ホントに、コーディングは正しいんです。
その幻想をぶち壊すこと。
0043デフォルトの名無しさん
2010/01/07(木) 21:41:53> い。 コンストラクタでNULLを入れる。
> ろ。 init()で領域確保。
まずコンストラクタとinitを分ける必要が無い。しかもinitを忘れないように徹底するのが難しい。
NULLがあるとNULLの場合の動作も対応する必要がありプログラムを安定させるのが難しくなる。
> は。 失敗したらNULLを入れる。
newで失敗すると例外が投げられるので意味が無い。
> に。 deleteしたらNULLを入れる。
> ほ。 デストラクタで開放する。
>は、徹底してます。
これらの徹底は難しいよ。参照とRAIIとスマポを使おう。ともかく生ポは扱わないのが近道。
追伸 目で見て確認は徹底とは言えないので注意
00441
2010/01/07(木) 21:55:51ダメでした。deleteを一切しなくても、newで落ちます。
>> 12
やり方が良く分かりませんでしたが、異常終了ポイントや変数値の
チェックはできました。printfデバッグで異常終了するnewの直前まで
正しい値が出力される変数ですら、異常終了時にはめちゃめちゃに
破壊されてます。それどころか、プログラム全般にわたり変数の多くの
値がデタラメに改竄されてます。
>> 23, 27, 29
確かにそのようですね。勉強になりました。ただ、今回はそう簡単でも
ありません。例外をキャッチするコードを挿入しましたが、とにかく
newの途中で異常終了するので役に立ちません。
>> 24, 42
コーディングは合ってると書いたのは、単に質問だけすると、
ポインタの扱いとかdeleteの失敗とかそういう初心者向けの
コメントしか来ないだろうと思ったので、敢えて書きました。
コーディングとは別のところで良く陥るミスとかないですか。
例えば、コンパイラオプションを間違えてるとか。
>> 28
メモリ管理の問題の可能性が高いとは私も思っています。
ただ、newで落ちるというのが解せません。例え、メモリ
管理が間違っていて、誤った代入がされていたとしても、
newで落ちますか?どんな時に、newで異常終了しますか?
00451
2010/01/07(木) 22:02:19嬉しいんですが、このデバッグが終わらないと、心から喜べません。
よろしくお願いします。
0046デフォルトの名無しさん
2010/01/07(木) 22:04:5200477
2010/01/07(木) 22:10:220048デフォルトの名無しさん
2010/01/07(木) 22:31:290049デフォルトの名無しさん
2010/01/07(木) 22:44:45>コーディングとは別のところで良く陥るミスとかないですか。
その幻想をぶち壊さないと前に進めないよ。
とりあえず、落ちる最小のコードをupしてごらん。
0050デフォルトの名無しさん
2010/01/07(木) 22:55:18■ このスレッドは過去ログ倉庫に格納されています