C・C++Debug日記2


※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。


ダイアログベースのMCFでメインダイアログのIDを変えてしまった!

1.現象
エラーメッセージなし。デバッグ画面に飛ばされる。
デバッグでは
Question.exe の 0x78a5b4d9 (mfc90ud.dll) でハンドルされていない例外が発生しました: 0xC0000005: 場所 0xfefeff66 を読み込み中にアクセス違反が発生しました。
と書かれ、winmain.cppファイルの42行目の
pThread->m_pMainWnd->DestroyWindow();
部分が指定される。
2.原因
タイトル通りメインとなるダイアログのIDを誤って変更してしまった。
3.解決方法
もう一つダイアログベースのMFCプログラムをテンプレートから作成しIDの名前の傾向を確認した。IDの名前は
IDD_プロジェクト名_DIALOG
となっている模様。これを探し、選択するべし。

Debug Assertion Failed!2

1.ErrorDialog

Microsoft Visual C++ Debug Library

Debug Assertion Failed!
Program: ...kolab\~~.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\strftime.c
Line: 832
Expression: ( "Invalid format directive" , 0 )
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)

中止(A) 再試行(R) 無視(I)

2.現象
ビルドは通る。実行すると上記のダイアログが出て止まる。
3.原因
Expression: ("Invalid format directive", 0)と書いてある通り不適切な形式で指定していた。具体的には
CTime ct;
CString cs;
cs = ct.Format( _T("%H:%M:%s"));
において小文字の「%s」を使ってしまった。大文字が正しかった。
3.Link
CTime@MSDN
Formatの指定子について@MSDN

Debug Assertion Failed!

1.ErrorDialog

Microsoft Visual C++ Debug Library

Debug Assertion Failed!
Program: ...ekolab\修論\Program\シミュレーション\Simulation@VS2008\Debug\Dialog.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\vsprintf.c
Line: 244
Expression: ("Buffer too small", 0)
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)

中止(A) 再試行(R) 無視(I)

2.現象
ビルドは通る。実行すると上記のダイアログが出て止まる。
3.原因
Expression: ("Buffer too small", 0)と書いてあるぐらいだからバッファが小さかった。
char hoge[10];
と10文字しか格納できないcharacterを定義していた。
3.解決方法
いっそchar hoge[99];とした。

MFCにおけるエラー処理

1.構文
char sHoge[40];
sprintf_s( sHoge, "Load/%s/%02d.bmp", sNameHeader, nTaskObjectNum );
if( cvLoadImage( sHoge ) == NULL )
{
CString strData;
strData.Format("画像%sは存在しません。",sHoge);
AfxMessageBox(strData,MB_ICONSTOP);
}
m_iplImage = cvLoadImage( sHoge ); // ここでm_iplImageに読み込まれた
2.使用条件
(1)MFC、(2)IplImageの読み込み部分、(3)画像イメージがない場合があった
3.Link
メッセージボックスの使い方 その1(AfxMessageBox)
メッセージボックスの使い方 その2(AfxMessageBox)
AfxMessageBoxを使う上での注意点
AfxMessageBox の使い方
考えのもとになったページ

MFCにおいてプログラムが開始できない2

1.ErrorMessage

OpenCV GUI Error Handler

Bad argument (Array should be CvMat or IplImage)
in function cvGetSize, C:\User\VP\opencv\cxcore\src\cxarray.cpp(1453)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).

中止(A) 再試行(R) 無視(I)

2.現象
MFCにおいてプログラムを起動しようと「ctrl + F5」をクリックすると上記のエラーメッセージが出て起動しない。ビルドは通る。
3.原因
画像の読み込みミス。画像がなかった。プログラム上で読み込む数と実際にフォルダ内で用意した画像数が異なっていた。似たようなエラーを2回繰り返していることからも今後はエラー処理を作っておくべきか?

MFCにおいてプログラムが開始できない1

1.ErrorMessage

OpenCV GUI Error Handler

Null pointer ()
in function cvGetRotationMatrix, C:\User\VP\opencv\cv\src\cvimgwarp.cpp(1197)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).

中止(A) 再試行(R) 無視(I)

2.現象
MFCにおいてプログラムを起動しようと「ctrl + F5」をクリックすると上記のエラーメッセージが連続的に出て起動しなくなる。処理が止まっている様子はない。とにかく「中止(A)」ボタンを押して処理を止めるしかない。
3.原因
オブジェクトの指定ミス。存在しないオブジェクトのメンバ関数を呼び出していた。「Null pointer ()」からも存在しないポインタを呼び出した可能性を示している。
今回バグが見つかったのは全くの偶然でありプログラミングには高い注意力が必要であると改めて認識した。

switch文による処理の変更ができない

1.現象
優先度判定シミュレーションプログラムにおいてロボットの動作制御をswitch文で行っていたが、最初のcase 0しか動作しなかった。
2.原因
switch文の判定変数であるm_nStateの初期化部分がわからず、 とりあえずswitch文の直前でm_nState=0;としていた。
よってm_nStateの変更が反映されず次の処理が行われなかった。
3.教訓
連続処理におけるswitch構文を使用する際は判定変数の初期化場所を気をつけなければいけない。
連続処理で常に初期化されてしまうと連続処理中の変更まで初期化されてしまう。

libcvdのコンパイルが通らない

1.ErrorMessage
構文エラー C2059 ','が使えないよ
2.エラー場所
3.原因
互換性のために残されているキーワードnear,farを変数に使っていた。
4.解決方法
near,farを他の名前に変更
5.その他C++で使えないキーワード
near far huge
上記の言葉を入れてもint,ifなどのように文字の色が変わることはないので要注意、MicroSoft Visual studio C++ 6.0と2005では使わないように(他のC++コンパイラーは不詳)。

cvReleaseImageDataが見つからない

1.ErrorMessage
error C3861: 'cvReleaseImageData': 識別子が見つかりませんでした c:~~cvext.hpp
2.原因
OpenCVの古いバージョンの関数を使っている?
3.解決方法
古い関数を全て消す。現在は難しいのでとりあえずcvext.hを引き続き使用する。
4.Link
掲示板

コンストラクタなのに返り値の指定が必要?

1.Error Message
error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません。
2.エラーで指定された部分
class 【クラスA】
{
public:
operator=(const 【クラスA】 &sss);  //←エラー発生
};
上記のようにoperatorが付いているのが原因?
3.解決方法
operatorの頭にvoidか【クラスA】&を付ける。
4.Link
掲示板
5.まとめ
以下のエラーも一緒に出たが、上記のエラーを直したらでなくなった。

.sbrファイルが足りない

1.Error Message
エラー 4 error BK1513 : インクリメンタルでないビルドにはすべての .SBR ファイルが必要です。 BSCMAKE Dialog
warning BK4502 : 切り捨てられた .SBR ファイル '.\Debug\cvext.sbr' は .\Debug/Dialog.bsc 内にありません。 BSCMAKE Dialog
2.現象
下記の.sbr、.bscファイルの対策をとってみたところ上記のエラーメッセージが出た。
3.解決方法
一緒に出たエラーC4430を直せば解決した。

.bscファイルのバージョンが合わない

1.Error Message
error BK1515 : '.\Debug/Dialog.bsc': バージョンが適合していません。インクリメンタル ビルドができません。 BSCMAKE Dialog
2.現象
VC++6.0からVS2008へ開発環境を移したら発生。
3.解決策
(1).bscファイルを削除してリビルド→別のエラーが発生
(2)検索→MSDNしか出てこない。
一緒に出たエラーC4430を直せば解決した。

.sbrファイルが見つからない

1.Error Message
error BK1506 : ファイル '.\Debug\myWholeClass.sbr' を開けません。: No such file or directory BSCMAKE Dialog
2.現象
VC++6.0からVS2008へ開発環境を移したら発生。
3.解決策
なし。BK1506で検索してもMSDNしか出てこない。…どうする?
一緒に出たエラーC4430を直せば解決した。

HMENUのメンバがない

1.Error Message
error C2208: 'HMENU__ *' : メンバのない列挙型、構造体、共用体が定義されました。c:\program files\microsoft sdks\windows\v6.0a\include\winuser.h 2817
2.現象
VS2008で
ファイル→新規作成→プロジェクト→VsualC++→Win32→Win32プロジェクト→アプリケーションの種類→DLL (+ 追加オプション→シンボルのエクスポート)→完了
を選択してクラスライブラリを作成しようとすると上記のエラーメッセージが表示されビルドできない。
3.原因
HMENUはwinuser.h内で定義されていたのだが、誤ってHMENUの中身を消してしまった模様。
4.解決方法
winuser.hを検索→winuser.h内をHMENU周辺の関数で検索→HMENUの値を探す。
HMENU hMenu;
と変更。MicroSoft提供のファイルの中身を変えてしまうこともあるようだ。
5.Link
プッシュボタンについて(掲示板)
2chスレ
ネコ

LoadStringの引数がおかしい

1.EllorMessage
error C2065: 'IDS_HELLO' : 定義されていない識別子です。
2.原因
開発環境をVisual Studio 2008 へ変更したため6.0でWindowsプロジェクトを作成する際選択できた「単純なHello World! アプリケーション」がなくなった。それに伴ってLoadSting関数の第二引数であるWindows の文字列リソース IDの名前が変わった。
3.解決策
Resource.hファイルを確認し「IDS_~~」の名前で定義されているマクロの名前を探し、それに変更する。
IDS_HELLO
↓
IDS_APP_TITLE
4.今回の解決策を見つけるまでの手順
  1. LoadStringをVC2008のMSDNで検索。第二引数について調べる
  2. IDS~~について書いてありそうな部分を探す。今回は「.rcファイル」→「Resource.h」の二手順で見つかった。
  3. IDS_~~ぽい値を見つける→試してみる→解決

クラスの継承がうまくいかない

1.ErrorMessage
error C2614: 'MyClass2' : イニシャライズ リスト内のクラス 'MyClass1' が基本クラスでもメンバでもありません。
2.原因
コーディングミス。派生クラスの定義において継承をしていなかった。
3.解決策
class MyClass2{
↓
class MyClass2 : public MyClass1 {

Hello World!プログラムさえ作れない

1.error message
エラー 1 error C2065: 'szHello' : 定義されていない識別子です。
2.原因
(1)szHelloは実際に定義されていなかった。
(2)開発環境をVisual Studio 2008 へ変更したため文字セットがunicodeに変更されたことによって文字列の格納ができなくなった。
3.解決方法
(1)charでszHelloを定義
(2)szHelloを使用するDrawTextの引数を変更
DrawText( hdc, szHello ,       strlen( szHello ), &rt, DT_CENTER );
DrawText( hdc, TEXT("Hello World!") , strlen( szHello ), &rt, DT_CENTER );

DLLファイルの関数作成場所ミス

1.error message
エラー 1 error C2144: 構文エラー : 'long' は ';' によって先行されなければなりません。
エラー 2 error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません
2.原因
開発環境をVisual Studio 2008 へ変更したため教科書の記述と合わなくなった。
3.解決方法
Visual Studio 2008 では
dllmain.cpp : DLL アプリケーションのエントリ ポイントを定義します。
MyDll1.cpp (※プログラム作成時に自分でつけたプロジェクト名) : DLL アプリケーション用にエクスポートされる関数を定義します。(こちらが自分で作った方)
の2種類存在する。新しくクラスを作成する場合はMyDll1.cpp側に作成する。

UnicodeとSHIFT-JIS関係3

1.Error Message
error C2664: 'CnstDst::CnstDst(char *)' : 1 番目の引数を 'const wchar_t [22]' から 'char *' に変換できません。
2.原因
(1)開発環境がVisual Studio 2008 に移り、基本の文字セットにUnicodeを使用するように変更されたため。
(2)さらに今回は関数の引数で char *s を渡しているので変数をTEXT("")で囲むわけにはいかない。
以下に Unicode文字セット下における文字列操作方法 をまとめておく
3.解決方法
(1)使用する変数の型を変更
char sDat[80];// 文字列型のメンバ変数
↓
wchar_t sDat[80];
(2)引数の型を変更
CnstDst( char *s );// コンストラクタ
↓
CnstDst( wchar_t  *s );
(3)入力する文字列をTEXT("")で囲む
CnstDst cd( "文章" );
↓
CnstDst cd( TEXT("文章"));
4.Link
wchar_tについて

UnicodeとSHIFT-JIS関係2

1.error message
エラー 1error C2664: 'atoi' : 1 番目の引数を 'TCHAR [80]' から 'const char *' に変換できません。(新しい機能 ; ヘルプを参照)
2.原因
開発環境がVisual Studio 2008 に移り、基本の文字セットにUnicodeを使用するように変更されたため。
3.解決方法
(1)使用する関数を変更する(推奨)
a = atoi( sBuff );//Unicodeではatoiを使えない
↓
a = _wtoi( sBuff );// 代わりに_wtoiを使う
(2)文字セットを変更する
メニューバー→プロジェクト→~のプロパティ(ソリューションエクスプローラーから表示してもよい)→構成プロパティ→全般→プロジェクトの既定値→文字セット
において「Unicode文字セットを使用する」から「マルチバイト文字セットを使用する」に変更する。
4.Link
CStringからint型への変換について(掲示板)
_wtoiへの変更について

UnicodeとSHIFT-JIS関係1

1.エラーメッセージ
error C2664: 'lstrcpyW' : 1 番目の引数を 'char [80]' から 'LPWSTR' に変換できません。(新しい機能 ; ヘルプを参照)
2.原因
VisualStudio2005からデフォルトの文字セットがUnicodeに変更された。以前はShift_JISだった。この変更によりlstrcpyやMessageBoxにcharで日本語を表示できなくなった。
3.解決方法
(1)プロジェクト全体でShift_JISを使えるようにする
メニューバー→プロジェクト→~のプロパティ(ソリューションエクスプローラーから表示してもよい)→構成プロパティ→全般→プロジェクトの既定値→文字セット
で「マルチバイト文字セットを利用する」に変更する。
(2)lstrcpy関数でShift_JISを使えるようにする
文字列の前に「TEXT」を付ける。例えば
wcex.lpszClassName = "ModelApp";
↓
wcex.lpszClassName = TEXT("ModelApp");

アクセラレータが使えない

1.ErrorMessage
エラー1 error C2065: 'IDR_ACCELERATOR1' : 定義されていない識別子です。 c:\t.h\kanekolab\修論\program\シミュレーション\~~.cpp59
2.原因
エラーC2065の通りIDR_ACCELERATOR1が定義されていない。IDR_ACCELERATOR1はコードとは別に作らなければいけない様子。
3.解決方法
IDR_ACCELERATOR1の作り方…調査中

リソースファイルが「他のエディタで使用中」になって使えない

1.原因
resource.hを開くと起きる現象。
2.解決方法
resource.hを閉じる。

BB1からBB2への移行方法まとめ1

1.基本手順
(1)BB2の基本動作プログラム(カメラから画像を取って表示するヤツ)からひたすらコードを投入。この段階では基本的にコードを消さない。
(2)BB2から得られるもの確認。今回は
triclopsContext , triclopsInput , triclopsImage , IplImage(Color , Rect , Edge , Disp)
(3)BB1上のプログラムと対応するものとの違い確認→変換
(4)triclops関係は変換不可能なので直接書き換え(距離取得部分とか)
2.躓いた所
(1)IplImageの〔チャンネル、ビットデプス、サイズ〕の確認を怠りcvGetMatでエラーを連発&混乱に陥る。以下のエラーメッセージがよく出た。

OpenCV GUI Error Handler

Null pointer (The image has NULL data pointer)
in function cvGetMat, C:\User\VP\opencv\cxcore\src\cxarray.cpp(2794)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).

中止(A) 再試行(R) 無視(I)

(2)画像変換の知識不足(チャンネル数変更、Header⇔Image変更)
(3)距離検出はtriclopsImageを使用していることに途中まで気付かなかった(triclopsContextなどの変更が遅れた)
(4)定義はされているが、メモリが確保されていないものがあった。
今回はHSVImageとRGBImage。
よって、以下を追加
HSVImage = cvCreateImage( cvSize( m_nImageWidth, m_nImageHeight ), IPL_DEPTH_8U, 3 );
BGRImage = cvCreateImage( cvSize( m_nImageWidth, m_nImageHeight ), IPL_DEPTH_8U, 3 );

ハンドルされていない例外4

1.ErrorMessage
~~~.exe の 0x7c94fe40 でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x00000100 を読み込み中にアクセス違反が発生しました。
2.原因
コードミス。
3.解決策
以下のように変更した。
wsprintf( s, TEXT( "KeyCode = %0x, Ctrl = %s, Shift = %s, Caps = %s",	wParam, ctrl, shift, caps));
↓
wsprintf( s, TEXT( "KeyCode = %0x, Ctrl = %s, Shift = %s, Caps = %s"),	wParam, ctrl, shift, caps);
4.考察
  1. ハンドルされていない例外→使用している関数に与える引数の失敗。値のミスではなく、引数部分の形が間違っている場合が多い?
  2. 「0x7c94fe40」や「0xC0000005: 場所 0x00000100」などに深い意味はない。文字通り場所を表しているのみ。
  3. デバッガで指定された部分のコードをよく読んだ方が解決の近道になる?

オーバーロード関数の呼び出しを解決することができません

1 原因
Visual C++で作られたプログラムをVisual studio 2008で動かそうとした。
今回はfmodとfabsというオーバーロート関数がエラーになった。
2 解決策
visual studioではfmad、fabsともに中の数値をdouble型にするという決まりになったため、数値の前に(double)を加えた。
compare_l=fabs(Passage[0].x-obstacle1.x);

compare_l=fabs((double)Passage[0].x-obstacle1.x);
こんな感じ。

未解決の外部シンボルが参照されない。

1 原因
MiniBeeからBB2に変更するときでたエラー。
2 解決策
プロジェクトのプロパティ→構成プロパティ→リンカ→入力→追加依存のファイル
に、以下を追加するだけ
pgrflycapture.lib
pgrflycapturegui.lib
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。