トップページ⇒tech
455コメント137KB

new/deleteで異常終了する(Visual C++)

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2010/01/06(水) 20:35:52
大変、困っています。
Visual C++ 2008でコーディングしています。
コーディングは何度も何度も見直しました。
間違っていません。

なのに、実行するとnewで異常終了します。
debug版で動かすと動きます。release版で動かすと異常終了します。
デバッグのしようがありません。

ホントに、コーディングは正しいんです。
こういう症状の原因って何が考えられるでしょうか。

よろしくお願いします。

deleteでも異常終了します。
未初期化ポインタのdeleteとかそんなのではなくて、
本当にコーディングはあってるのに、異常終了します。

動きは、毎回違います。
例えば、printfデバッグをしようとしてprintfを
挿入すると、異常終了ポイントが変わります。
でも、newかdeleteで落ちます。

ホントに、ホントに、コーディングは合ってるのに
どうしようもありません。

もう何ヶ月も仕事が進みません。
このままだと、クビになっちゃいます。

お願いします、本当に、よろしくお願いします。
0002デフォルトの名無しさん2010/01/06(水) 20:43:53
それは大変だ!今すぐマイクロソフトのVisual C++ の開発責任者に電話しろ!
0003デフォルトの名無しさん2010/01/06(水) 20:55:46
コーディングを見直す前に
ローカルルールを見直せ
0004デフォルトの名無しさん2010/01/06(水) 21:08:29
┐(´ー`)┌ < サッサト クビニナレ
0005デフォルトの名無しさん2010/01/06(水) 21:18:13
このスレッドは天才チンパンジー「アイちゃん」が
言語訓練のために立てたものです。

アイと研究員とのやり取りに利用するスレッドなので、
関係者以外は書きこまないで下さい。

                  京都大学霊長類研究所
0006デフォルトの名無しさん2010/01/06(水) 21:23:08
>>1
これってdelete文を全部コメントアウトしても症状は同じ?
一再deleteしなくても一応は動くでしょ。deleteしないとメモリーオーバフローしちゃう?
0007デフォルトの名無しさん2010/01/06(水) 21:56:28
newで異常終了するってことは破壊されてる
0008デフォルトの名無しさん2010/01/06(水) 22:00:39
世界が?
0009デフォルトの名無しさん2010/01/06(水) 22:10:08
再インストールはしましたか??
0010デフォルトの名無しさん2010/01/06(水) 22:11:24
たぶん、間違ってないよ
0011デフォルトの名無しさん2010/01/06(水) 22:12:04
>>1
単発の質問でスレ立てはマナー違反な。
いちおう言っとくけど。
0012デフォルトの名無しさん2010/01/06(水) 22:12:54
2008ってリリースモードでもデバッグできない?
0013デフォルトの名無しさん2010/01/06(水) 22:13:09
ショートカットに Visuaru C++ って書いてないかチェックした方が良いな
001412010/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 ; } ;
} ;
001512010/01/06(水) 22:41:54
とにかく、
 い。 コンストラクタでNULLを入れる。
 ろ。 init()で領域確保。
 は。 失敗したらNULLを入れる。
 に。 deleteしたらNULLを入れる。
 ほ。 デストラクタで開放する。
は、徹底してます。

上記、C2の例みたく、デストラクタが
どんどん直列に呼び出される場合があります。
001612010/01/06(水) 22:43:06
> 6
いま、家なので、明日会社でやってみます。
もし仮にdeleteしないでうまくいったら、
deleteが原因ってことですか?

> 7
何が破壊されていますか。
破壊のよくある失敗原因はありますか。

> 11
ごめんなさい。しりませんでした。次から気をつけます。
でも、ネットで調べても全然のってないんです。
もう、2chにアクセスするエリートプログラマしか
頼れないんです。

> 12
えっ、そんな方法あるんですか。
明日会社でトライしてみます。
0017デフォルトの名無しさん2010/01/06(水) 22:44:37
>>14
んー、特に問題は見あたらないなー
0018デフォルトの名無しさん2010/01/06(水) 23:07:37
>>16
もし、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:18
NULLポインタはdeleteしても問題ないだろ。
0020デフォルトの名無しさん2010/01/06(水) 23:14:04
ま、C1型の値をコピーしちまってるオチだろうな。
0021デフォルトの名無しさん2010/01/06(水) 23:22:46
>>19
これはスマン。NULLポインタにdeleteしたことなんか無かったもんで。
0022デフォルトの名無しさん2010/01/06(水) 23:34:14
今日の魚影は濃いな
0023デフォルトの名無しさん2010/01/07(木) 00:13:19
そもそもnewが失敗した場合はNULLじゃなくて例外飛ぶから根本から間違えてんだけどな。

俺の感で言うと暗黙のoperator=でポインタをコピーして二重deleteとみた。
0024デフォルトの名無しさん2010/01/07(木) 00:14:28
> コーディングは何度も何度も見直しました。間違っていません。
ぼくわるくないもん! ぼくわるくないもん! ぼくわるくないもん! ぼくわるくないもん!
> なのに、実行するとnewで異常終了します。
わるいのはかんきょうだ! ぼくわるくないもん!

って時点でもうね。
ガチで書いているなら向いていないから辞めなさい。社会人を。
ネタで書いているなら向いていないから辞めなさい。人間を。
0025デフォルトの名無しさん2010/01/07(木) 00:17:12
しかし、何が悲しいって仕事でC++書いてるやつがこのレベルということ。
正直初心者がC++とかやると周りが不幸になるからやめたほうがいいよなー。

>>24
俺はC++で間違いなく書けたなんてRAII徹底しないと自信を持てないな。
生のポインタ使いつつ自信を持てる人をある意味、尊敬する。ある意味な。
0026デフォルトの名無しさん2010/01/07(木) 00:21:54
destructorに一個一個debug文を入れてどこでオチてるか
調べるのが定石
0027デフォルトの名無しさん2010/01/07(木) 00:40:55
>>23
一応、古い処理系だとnew失敗でnullが返る(std::nothrowなしでも)のはあるが…
自分はVS2008は使わんので分からないが、どっちなのだろうか?
>>25
烈しく同意。自分はC++に限らず「間違っていない」なんて口が割けても絶対に言えんわ。
0028デフォルトの名無しさん2010/01/07(木) 01:05:45
>>26
このパターンだと、多分それだと捕まらないんじゃないかなぁ。
> 動きは、毎回違います。
ってことだから。

アホの書いたコードがビルドやprintfデバッグで挙動が変わる場合、高確率でメモリ破壊やメモリ未初期化が原因。
それにより、バイナリが変わる度にヒープやスタック(やそこに残ったゴミ)の状況が変化し現象が変化する。
そしてほぼ全てのアホは、根拠皆無なのに何故か肥大化したプライドを守るために
目が曇って and/or 意図的に目を曇らせ、いくらコードを見てもそれを発見できずに自分以外の何かが原因だと喚く。

> このままだと、クビになっちゃいます。
それはヤバいね。先手を打って自分から退職願を出せば自分都合になるし退職金ももらえるよ?
0029デフォルトの名無しさん2010/01/07(木) 01:11:47
>>27
Visual C++ 6.0がNULLを返す最後の世代。

2008は9.0だから(数ヵ月後には2010(10.0)が出る)
普通のnewでNULLが帰ってくるのは現在考慮する必要は殆どないかと。

# 昔からのコードの保守で使わざるを得ない不幸な環境の人も多少はいるでしょうが
0030デフォルトの名無しさん2010/01/07(木) 01:40:16
しかもSTLは例外返すことを前提に作られてるから
メモリ無くなったらNULL参照で落ちるという糞処理系
まあ例外投げるようにすることはできるから
そうすりゃいいだけの話ではあるが
0031デフォルトの名無しさん2010/01/07(木) 02:48:05
operator=()とコピーコンストラクタをprivateに宣言して、
コンパイルが通るかどうか
0032デフォルトの名無しさん2010/01/07(木) 03:33:10
最善案
C++じゃなくC#或はJavaで書いてみる。
十分本質的なコードが出来た後にC++に移植する。
プログラムに課せられている問題と、C++特有の
技術上の問題がごっちゃになると難しい。(特に
VCは細かい技術上の配慮が必要で繊細)
(いきなりC++で完璧なコードを作ること自体に無
理がありそう。それなりにCやC#,Javaの経験があっ
たほうがいい)
C++コード書けるんだったらJava,C#の
コードを書くのはそれほど難しくは無い。
ただライブラリ関数の名前を覚えたり
調べたりするのがちょっと最初はきついかも
0033デフォルトの名無しさん2010/01/07(木) 04:04:28
どこが最善なのか。
0034デフォルトの名無しさん2010/01/07(木) 04:17:41
バグッたC/C++コードのデバッグだけはしないほうが
良い。精神衛生上問題が大有りだから。
仕様書がある限り、潔くそのコードを捨てて
書き直すのが最善。
JavaやC#とかのようなものでもそれが言える
C++だったら尚更。
0035デフォルトの名無しさん2010/01/07(木) 04:20:11
>>34
急がば回れ
でつねw
0036デフォルトの名無しさん2010/01/07(木) 05:06:19
プログラミング言語c++隅から隅まで読めば
>>14のコードじゃバグるのわかるだろ
0037デフォルトの名無しさん2010/01/07(木) 05:11:22
> ホントに、コーディングは正しいんです。
?
0038デフォルトの名無しさん2010/01/07(木) 05:20:48
Javaとかだったら
class c;
と
class[] c;
を混同しようものならコンパイルが通らないから
そういった系統のバグは発生しない点では初学者には優しいか...
0039デフォルトの名無しさん2010/01/07(木) 06:06:55
なるべく自分でメモリ管理しない
new C2[5] とかしないで std::vector<C2> を使う
添え字の範囲もチェックする
0040デフォルトの名無しさん2010/01/07(木) 07:31:38
クビになったらまた教えてね
0041デフォルトの名無しさん2010/01/07(木) 17:05:03
1は勤め先間違えたような感じが
0042デフォルトの名無しさん2010/01/07(木) 20:48:08
>>1 まず最初にするべきなのは、そげぶ
>ホントに、コーディングは正しいんです。
その幻想をぶち壊すこと。
0043デフォルトの名無しさん2010/01/07(木) 21:41:53
>>15そのコーディングスタイルは効果が薄い上に問題がある。

> い。 コンストラクタでNULLを入れる。
> ろ。 init()で領域確保。
まずコンストラクタとinitを分ける必要が無い。しかもinitを忘れないように徹底するのが難しい。
NULLがあるとNULLの場合の動作も対応する必要がありプログラムを安定させるのが難しくなる。

> は。 失敗したらNULLを入れる。
newで失敗すると例外が投げられるので意味が無い。

> に。 deleteしたらNULLを入れる。
> ほ。 デストラクタで開放する。
>は、徹底してます。
これらの徹底は難しいよ。参照とRAIIとスマポを使おう。ともかく生ポは扱わないのが近道。

追伸 目で見て確認は徹底とは言えないので注意
004412010/01/07(木) 21:55:51
>> 6, 18
ダメでした。deleteを一切しなくても、newで落ちます。

>> 12
やり方が良く分かりませんでしたが、異常終了ポイントや変数値の
チェックはできました。printfデバッグで異常終了するnewの直前まで
正しい値が出力される変数ですら、異常終了時にはめちゃめちゃに
破壊されてます。それどころか、プログラム全般にわたり変数の多くの
値がデタラメに改竄されてます。

>> 23, 27, 29
確かにそのようですね。勉強になりました。ただ、今回はそう簡単でも
ありません。例外をキャッチするコードを挿入しましたが、とにかく
newの途中で異常終了するので役に立ちません。

>> 24, 42
コーディングは合ってると書いたのは、単に質問だけすると、
ポインタの扱いとかdeleteの失敗とかそういう初心者向けの
コメントしか来ないだろうと思ったので、敢えて書きました。
コーディングとは別のところで良く陥るミスとかないですか。
例えば、コンパイラオプションを間違えてるとか。

>> 28
メモリ管理の問題の可能性が高いとは私も思っています。
ただ、newで落ちるというのが解せません。例え、メモリ
管理が間違っていて、誤った代入がされていたとしても、
newで落ちますか?どんな時に、newで異常終了しますか?
004512010/01/07(木) 22:02:19
話変わりますが、今日、情報処理の合格証書が届きました。
嬉しいんですが、このデバッグが終わらないと、心から喜べません。
よろしくお願いします。
0046デフォルトの名無しさん2010/01/07(木) 22:04:52
C2 クラスが怪しい
004772010/01/07(木) 22:10:22
俺の指摘が正しかったようだ
0048デフォルトの名無しさん2010/01/07(木) 22:31:29
>>38あたりが良いヒントかな
0049デフォルトの名無しさん2010/01/07(木) 22:44:45
>>44 そげぶ
>コーディングとは別のところで良く陥るミスとかないですか。
その幻想をぶち壊さないと前に進めないよ。

とりあえず、落ちる最小のコードをupしてごらん。
0050デフォルトの名無しさん2010/01/07(木) 22:55:18
deleteで例外吐くときってポインタがマイナス方向に走ってヒープ壊してる以外にないよね
0051デフォルトの名無しさん2010/01/07(木) 23:06:54
>>44
まず、その「俺のノーミソは機能している」という幻想をぶち壊す。

> メモリ管理が間違っていて、誤った代入がされていたとしても、newで落ちますか?
相も変わらず、ぼくわるくないもん!!!か。

あらゆる参照可能なメモリにあらゆる値が存在しうる場合に発生しうる全ての現象が起こる。
電卓ソフトがメモリ破壊が原因で暴走し、突如モナリザの絵を200枚連続で
プリンタから出力することもありうる。しかもカラーで。
0052デフォルトの名無しさん2010/01/07(木) 23:07:26
>>12
VisualStudio2008はりリースモードでもデバッグ情報作るからデバッグできるよ。
0053デフォルトの名無しさん2010/01/08(金) 00:04:39
まぁ他人に問題解決頼むなら問題を発生させる最小のコードが必要だよね。
# とはいえそこまで出来たら後は自分で殆ど解決してしまうけど
0054デフォルトの名無しさん2010/01/08(金) 00:45:37
> コーディングは合ってると書いたのは、単に質問だけすると、
> ポインタの扱いとかdeleteの失敗とかそういう初心者向けの
> コメントしか来ないだろうと思ったので、敢えて書きました。
> コーディングとは別のところで良く陥るミスとかないですか。
> 例えば、コンパイラオプションを間違えてるとか。
これはどうみても
「お前らごときが俺のプログラムの不具合を詮索ことが許されると思っているか。
 お前らが思うような不具合など、俺様のプログラムに存在することなど絶対にありえない。
 俺様のプログラムが完全であると認め、それ以外の不具合の原因を俺様のために追求せよ」
と言っているのに等しい。

もうね、こんな奴プログラマー失格とか社会人失格とかってレベルじゃない。
会社にいたら死力を尽くして距離を置いて、接近されぬよう逃げるべき相手。
もはや>>44の一番適切な回答は、「ハイソーデスネ、アナタノプログラムモンダイハアリマセンヨ」だ。
(参考文献 http://glossary.tank.jp/t0018.html)
0055デフォルトの名無しさん2010/01/08(金) 08:15:19

他のPCでコンパイルしてみたら?
005672010/01/08(金) 08:22:33
Cで長年、生ポインタ使った経験が無いとC++を使うのは難しい
0057デフォルトの名無しさん2010/01/08(金) 09:10:57
「コンパイルが通る」=「完璧なシンタックスだ」=「おれは間違ってない!」とかよくある話で。

まあ向いてないんだろうね。
0058デフォルトの名無しさん2010/01/08(金) 09:12:25
main関数で他のルーチンに飛ばす部分を一切コメントアウトして適当な配列だけnewしてみたらどうなるの?
0059デフォルトの名無しさん2010/01/08(金) 09:32:20
C2のコンストラクタがぶっ壊れてんじゃねーの?
0060デフォルトの名無しさん2010/01/08(金) 10:29:40
アドヴァイスしてるやつも同類のアホだなw
0061デフォルトの名無しさん2010/01/08(金) 12:22:20
どういう条件で落ちるのかも正確に出てないのに解決なんてするわけ無いだろう。
どういう条件で落ちるのかも正確に書けない奴のコードが正しいはず無いだろう。
0062デフォルトの名無しさん2010/01/08(金) 14:09:29
メモリが破壊されるタイミングだと考えている瞬間よりもっと前にメモリアロケータの管理領域を破壊している
既に致命傷を受けていてdeleteでとどめを刺されているだけ
0063デフォルトの名無しさん2010/01/08(金) 15:42:11
おそらくbuffer overrun
0064デフォルトの名無しさん2010/01/08(金) 15:45:52
c[5]とか書き換えてるよね
0065デフォルトの名無しさん2010/01/08(金) 16:17:06
たぶんこれで壊れるんだろ。>>14のコードから見て
c1 = c2;
or
C1 c1(c2);
0066デフォルトの名無しさん2010/01/08(金) 19:14:47
VCでdebugモードで動いて、rekeaseモードで動かないってオレもあった気がする。
なにが原因だったかは忘れた。

これって人のプログラムを直してるの?
そうじゃなかったら、最後に動いた状態まで戻せないの?
0067デフォルトの名無しさん2010/01/08(金) 21:13:09
>>60
間抜けなことに、本人も「アドバイスしてるつもり」だから
余計タチが悪いよな。
006812010/01/08(金) 21:36:31
今日ちょっと進展がありました。

クラッシュを起こすクラスを使用するプログラムの、
落ちる部分とはぜんぜん違うところのとあるコードを変更したところ、
newやdeleteでのクラッシュが起きなくなりました。

変更したところは、その部分のテストでは特に問題なくて、
その部分でエラーが起きたこともないんですが、ちょっとその部分の
コードを変えました。

すると、突然、しっかり動き出しました。

解決したと思っていいのか、よく分からないですが、
今日のところは問題は起きてません。
0069デフォルトの名無しさん2010/01/08(金) 21:39:26
直したコードのところでヒープぶっこわしてたんだろ。参考までにプロジェクトの名前教えてくれ。見掛けても使わないようにするから。
0070デフォルトの名無しさん2010/01/08(金) 21:42:31
よくわかんないけど動いたのでこれでいいです
007172010/01/08(金) 21:53:55
まあ動けばいいよ。またエラー出たときに考えればいいよ。
0072デフォルトの名無しさん2010/01/08(金) 21:57:06
>>14
おまえみたいな初心者は頼むからSTL使ってくれ。

#include <vector>

class C1 {
private:
// メンバ
std::vector<int> a;
std::vector<int> b;
std::vector<C2> c;
public:
// コンストラクタ
C1( void ) : a(5, 0), b(5, 0), c(5, C2()) {}
// デストラクタ
~C1( void ) {}
public:
// 初期化メソッド
int init( void ) { return 0; }
public:
// 各種メソッド
int xxx( xxx ) { xxx ; }
};
0073デフォルトの名無しさん2010/01/08(金) 22:01:14
>>72
おいおい…初心者に罠イクナイ。ここまで頭の悪い奴にSTLを使わせても
自分でデバッグできない不具合を埋め込んでゴネだすのがオチだぞ…

>>14
おまえみたいな初心者は頼むから会社もプログラマーも辞めてくれ
0074デフォルトの名無しさん2010/01/08(金) 23:25:52
ちゃんと動いてるんだから黙っててください
0075デフォルトの名無しさん2010/01/08(金) 23:30:59
>>74
え? 明らかに>>1のノーミソの不具合があるのに、
それによる観測結果が正しいだなんて誰が保証を(ry
0076デフォルトの名無しさん2010/01/08(金) 23:42:36
保証なんていらないし
0077デフォルトの名無しさん2010/01/08(金) 23:49:38
× ちゃんと動いている
○ 一見動いているように見える
◎ 動くか動かないか分からないが、今のところは落ちない

「ちゃんと動く」ってのと「今は落ちていない」の違いも理解できないのか?
0078デフォルトの名無しさん2010/01/08(金) 23:57:37
頻繁に落ちてたのが落ちなくなったなら99%直ってるよ
0079デフォルトの名無しさん2010/01/08(金) 23:57:48
別に言葉遊びしたいわけじゃないからどうでもいい

ちゃんと動くもちゃんと動いているように見えるも同じ
0080デフォルトの名無しさん2010/01/09(土) 00:05:41
今年はこういう白痴新人が入ってきませんように
0081デフォルトの名無しさん2010/01/09(土) 00:15:40
>>78,79
趣味のコードならそれでいいさ。誰も困らないからね。

>>80
この手のはマジで会社の寄生虫だよな…>>1のように他人のせいにして
学習せず原因を追求せず30過ぎても40過ぎても>>1と同レベルのコードを書く。
0082デフォルトの名無しさん2010/01/09(土) 00:55:17
>>81
別に>>1が汚いコード書こうが81は困らない
だからどうでもいいだろ。

おまえが>>1のコードで直接被害うけてるならともかく第三者のくせにごちゃごちゃいうなみっともない
■ このスレッドは過去ログ倉庫に格納されています