メモ
メモに全部突っ込んで書いていたら,まさかの「サイズがデカすぎて処理できませんエラー」がサーバから返されてしまった.
しょうがないので,C/C++系のトラブルだけこっちに移すことにした.
argcとargv †
int main(int argc, char **argv)
が一般的な宣言
arg uments c ount(argc), arg uments v alue(argv)と覚えよう
sizeof †
sizeof()の返り値
OS Windows XP FreeBSD コンパイラ VS 2008 VS 2005 .NET 2003 VS6 gcc(C) gcc(C++) cc(C) cc(C++) char 1 unsigned char 1 short 2 int 4 long int 4 float 4 double 8
ダイアログをMFCダイアログから呼び出すと反応が異様に遅い. †
C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_6b128700\msvcr80.dll
を読み出そうとして遅くなってるっぽ.
何故,読み出すようになったのか・・・それだけが分からないよ.
:未解決?
CTimeを使わずに時間を取得する †
time.hを使う
struct tm *timeinfo;
time_t timer;
timer = time(NULL);
timeinfo = localtime(&timer);
strftime(buffer, length, "%m%d-%H%M%S", timeinfo);
もっと短い時間(ミリ秒とか)を取得する場合はGetTickCount() とかを使うべし.
floatとdoubleの違いについて †
C++のprivateなポインタ変数をreturnで外に出す †
クラスでprivateで宣言したポインタ変数を,return でクラスの外に出すと,何も問題なく編集出来てしまう.
#include <stdlib.h>
#include <stdio.h>
class Hoge{
public:
Hoge( ) { memory = new int ;} ;
~Hoge( ) { delete memory;} ;
private:
int * memory;
public:
int * a( void ) { return memory;}
} ;
int main( int argc, char ** argv) {
Hoge * a = new Hoge( ) ;
int * b;
b = a-> a( ) ; //←ここで問題なくポインタを取得できる
* b = 5 ; //←ここで変更できてしまう
return 0 ;
}
private変数をreturnする段階でアウトなんじゃね?と思うんだが,コンパイラも実行時エラーも出ない.
ポインタが指す番地の中身は変更できるが、ポインタが指す番地自体は変更できない
enumの定義方法 †
いっつも忘れるので自分用のmemo
enum 型 {値1, 値2, ... 値N };
Example
enum the_sin {PRIDE, GLUTTONY, GREED, SLOTH, WRATH, ENVY, LUST};
実行時にMSVCR80.DLL (MSVCR80D.DLL?) が無いと言われる †
OpenCVのデバッグ用ライブラリとリンクした後,実行時に言われた.
以下の2点を修正
highguid.libを外した
highguid.libをビルドしなおし
あとcxcored.libをリンクすると,heapがどうの,と文句を言われた.
ジャンル:OpenCV :未解決?
fatal error C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 †
ジャンル:Visual Studio
fatal error C1020: 予期しない #endif です。 †
ジャンル:Visual Studio
fatal error C1033: †
おそらくテンポラリなエラー
Visual Studioでこれが起きる場合,IntelliSenseの更新とかぶって編集が出来ていない可能性があり.
ジャンル:Visual Studio
error C2062: 型 'char' は不要です。 †
smallと言う変数名は予約語
RpcNdr.hを(どういう経緯でincludeしたかは知らないが)includeすると,
#define small char
とされている.
と言うわけで,変数名smallを使用するとcharを宣言したことになり,上記のエラーが発生する.
レアなエラーかも.
ジャンル:Visual Studio
error C2064: 引数を取り込む関数には評価されません。 †
ジャンル:Visual Studio
error C2059: 構文エラー : サフィックスが無効です。 †
int 3DPoints[ 200 ] ; // <- 変数名の頭に数字は使えない
ジャンル:Visual Studio
error C2065: 'M_PI' : 定義されていない識別子です。 †
M_PIはmath.hで定義されてる円周率
しかし,math.hをincludeしただけではdefineされない
_USE_MATH_DEFINESをdefineする必要がある
ちなみにVC++6では定義されてないとのうわさ.
#define _USE_MATH_DEFINES // <-これが一番大事♪
#include <math.h>
int main( ) {
printf ( "%f\n " , M_PI) ;
}
ジャンル:Visual Studio
error C2381: 'exit' : 再定義 ; __declspec(noreturn) が異なります。 †
error C2679: 二項演算子 '<<' : 型 'const largeNumber' の右オペランドを扱う演算子が見つかりません (または変換できません)。 †
error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion) [duplicate]
cppunitを使ってテストをビルドしようとしたら、このエラーが出た。
下記、assertionを使うと、OStringStreamに << 演算子で出力する。
template < class T>
struct assertion_traits
{
static bool equal( const T& x, const T& y )
{
return x == y;
}
static std:: string toString( const T& x )
{
OStringStream ost;
ost << x; // error
return ost.str ( ) ;
}
} ;
このOStreingStreamはstd::ostringstream として、Stream.hに定義されている。
なので、この operator << を定義する必要がある
headerファイル
std::ostream& operator << (std::ostream& out, const class foo& right);
cppファイル
std::ostream& operator << (std::ostream& out, const class foo& right)
{
out << right.getString(); // 適当な処理を行う
return out;
}
後述 するように、ヘッダファイルと実装を切り分けないと、多重定義が発生するので注意。
error C3861: 'min'識別子が見つかりませんでした †
'max'も同じく
Visual Studio 2005からVisual Studio 2008に変更したら起きた
どうやら,min,maxは非標準のマクロだったらしい.
std::min, std::maxでリプレースするのが妥当かと.
std::max(a, b)
しかし,それでもダメなときがある.
error C2780: 'const _Ty &std::max(const _Ty &,const _Ty &,_Pr)' : 3 引数が必要です - 2 が設定されます。
引数にテンプレート関数を使ってる関係で,どうやら,引数の2つが違うtypeだとエラーの模様.
両方の引数の型が違うとこける模様.
double d = 1.0;
int i = 0;
std::max(i, d); // ←ここでdoubleとintの比較なのでこける
ってな具合に.
静的キャストを使って回避しよう
std::max(1.0, (double)0);
error D8016 : コマンド ライン オプション '/GL' と '/ZI' は同時に指定できません †
ジャンル:Visual Studio
warning C4390: プロトタイプされている関数が呼び出されませんでした (変数の定義が意図されていますか?) †
warning C4819:ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。 †
ジャンル:OpenCV :OpenCV 1.1 :OpenCV 2.0 :OpenCV 2.1 :Visual Studio
Visual Studio 2008 + OpenCV 2.2 ではlegacy/compat.hpp がこのwarningを出す.
上記方法では何故かwarningが消えない.
原因は追求中.
対症療法と根本的な解決方法を1つずつ
#pragma を使って warning を 抑制
#pragma warning(disable : 4819)
#include <cv.h>
#pragma warning(default: 4819)
正しいファイルをインクルードする
OpenCV 2.2 でファイル構造が大幅に変わった.
C++インタフェース用のファイルとCインタフェース用のファイルが別々になってる.
旧来の cv.h や cxcore.h のincludeも compatibility として残されている(build\include\opencv 以下のファイル達)
それらをincludeすると,上記C4819 warningが発生する.
対応するヘッダファイルを opnecv2 以下から探してくれば良い
cxcore.h <-> opencv2/core/core_c.h (Cインタフェース) opencv2/core/core.hpp (C++インタフェース)
cv.h <-> opencv2/imgproc/imgproc_c.h (Cインタフェース) opencv2/imgproc/imgproc.hpp (C++インタフェース)
highgui.h <-> opencv2/highgui/highgui_c.h (Cインタフェース) opencv2/highgui/highgui.hpp (C++インタフェース)
など(あくまでも一例)
いずれにしろwarningなだけなんだが.
ジャンル:OpenCV :OpenCV 2.2 :Visual Studio
warning C4800: 'int' : ブール値を 'true' または 'false' に強制的に設定します (警告の処理) †
warning LNK4098: defaultlib '*****' は他のライブラリの使用と競合しています。 †
ジャンル:Visual Studio
warning MSB8012: TargetPath does not match the Library's OutputFile †
0xc0150002 アプリケーションを正しく初期化できませんでした †
ジャンル:OpenCV :OpenCV 1.1 :Visual Studio
OpenCV 1.1でプロセス(プログラム)が終了しなくなる †
以下あたりを参照
SHBrowseForFolder APIとOpenCV 1.1 pre1を使うとプロセスが正常に終了できなくなるらしい.
聞いただけで,使ったこと無いので原因はつかめてない.
'Invalid allocation size'とか出るみたい
ジャンル:OpenCV :OpenCV 1.1 :Visual Studio :未解決?
関数を使用しただけで,突然大量の「型が定義されていません」エラーが発生する †
KLTの実装にて起きた.
原因というより,C言語で起きてたので,仕様とも言うべき事態.
KLTの本体はC言語で書かれている割に,メインプログラムはC++でコンパイルできる.
よって,メインプログラム内の適当な場所で関数をコールすると,それより後で宣言が行われていた場合,宣言が全てエラーになる.
初歩的な・・・
ジャンル:Visual Studio
Debug Assertion Failed! Expression: _pFirstBlock == pHead †
概要
DLL内で確保されたメモリを、DLL外で解放すると、"Debug Assertion Failed!"というダイアログが発生する可能性がある
発生条件
参考サイト *5 にも書いてあるが、いくつか条件がある
Visual Studio の設定でRuntime Library の設定を"Multi-threaded Debug (/MTd)"にしている場合
全部で/MDd、/MD、/MTd、/MTと4パターンあるが、/MTdの場合にしか起きない
DLL内部で確保したメモリ配列をDLLの外部で解放する
そのときに、Debug Assertion Failedが発生する
手元の環境
gtestを使ってテストプログラムを書いていたときに遭遇
gtestを使うためには、"Multi-threaded Debug (/MTd)"もしくは"Multi-threaded (/MT)"にする必要がある*6
さもないと、こんなエラーに遭遇する
error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in main.obj
で、Releaseではheapの状況とか確認しないので、見た目はエラーが起きてないように見える。
以下のようなプログラムで発生した (一部省略)
void function ( )
{
std:: vector < cv:: Point > imagePointsUndistorted; // このstd::vectorはこの時点で空っぽ
cv:: undistortPoints ( imagePoints, imagePointsUndistorted) ; // この関数(DLL)内部でstd::vectorにデータが追加される(=メモリ領域が確保される)
} // 返ってきたメモリ配列はこの関数から抜ける時点(DLL外部)で破棄される
Multi-ThreadedかMulti-Threaded DLLかは、ランタイムライブラリのことで、通常はdynamicリンク(実行時にロード)される
しかし、このためには、実行するコンピュータにランタイムライブラリが入ってる必要がある。これが/MDもしくは/MDdの選択 (Multi-threaded DLL、Multi-threaded Debug DLL)
/MTもしくは/MTdの選択にすると、利用するランタイムライブラリをstaticリンク(プログラムに埋め込み)される
プログラムサイズが増大するので、一長一短。
最後の小文字のdは、Debug版を意味し、メモリの配列外アクセスなどのチェックも行われる
このランタイムライブラリで管理される部分がまさにstd::vectorであり、この配列確保がDLL内部で行われていると、まずい。
解決方法
Visual Studio .NETでプロファイラを使う方法 †
Professional Edition のみ?
VC++の場合(多分ほかも同じだと思うけれど)
ビルド(B)→ガイド付き最適化のプロファイル(P)→インストルメント(I)を実行
リビルドが行われる
Debugモードだとerror D8016が出たので無理かも
ビルド(B)→ガイド付き最適化のプロファイル(P)→インストルメントまたは最適化されたアプリケーションの実行(R)
アプリケーションが起動するので,適当に動かす(最適化させたい動作がベスト)
アプリケーションを終了する
ビルド(B)→ガイド付き最適化のプロファイル(P)→最適化(O)
ツール(T)→Visual Studio 2005 Command Promptを実行
コマンドプロンプト上でコマンドを実行
C:\Program ... \VC\bin>pgomgr /summary XXXXXX\apli.pgd
XXXXXXにはアプリのReleaseフォルダへのパス
apliはソリューションの名前
これでこんな表示が出るはず.長いのでリダイレクト推奨
Microsoft(R) Profile Guided Optimization Manager 8.00.50727.762
Copyright (C) Microsoft Corporation. All rights reserved.
PGD ファイル: \XXXXXXXX\apli.pgd 11/20/2008 12:54:52
モジュールの数: 1 関数の数: 389 Arc の数: 1248 値の数: 18
静的命令: 11054 基本ブロック: 1743 平均 BB サイズ: 6.3
動的命令: 327756730
entry static dynamic % run
関数名 count instr instr total total
tSubtractAverage 307200 93 134351620 41.0 41.0
shift 1603470 90 44897160 13.7 54.7
C2TSI::getInnerProductMap 240 181 35021113 10.7 65.4
tLowPass 153600 322 34713600 10.6 76.0
tPadZero 307200 122 32070160 9.8 85.8
CTSI::SearchStartAndEnd 960 118 31556620 9.6 95.4
CTSI::extractRawColumn 307200 29 8908800 2.7 98.1
CTSI::getNormMap 480 58 3699360 1.1 99.2
CTSI::getTimeSpaceImage 1442 357 977770 0.3 99.5
_cvGetRow 40560 9 365040 0.1 99.6
CTSI::loadImageFromImageFile 20164 23 302460 0.1 99.7
CTSI::loadImageFromImageFile 20164 11 221804 0.1 99.8
右から3列目のdynamic instrが実行回数
右から2列目の%totalがその関数が実行に要した時間
一番右のrun totalが実行時間の累計和
次回ビルドするときに何か言われることがあるが,プロファイラをしないなら,リビルドを行ってよい.
ジャンル:Visual Studio
FILE*構造体 †
int fseek(FILE *fp, long offset, int whence); †
whenceからoffsetバイト分移動したところに移動する
whenceは,
ファイルの先頭を表すSEEK_SET
現在位置であるSEEK_CUR
終端位置であるSEEK_END
のどれか
void rewind(FILE *fp); †
FILE* fopen(const char *filename, const char *mode); †
コード要素*** が読み取り専用であるため、追加と削除操作は出来ません †
Visual Studio 2005で発生
MFCダイアログボックスにボタンを追加し,イベントハンラを追加しようとしたら発生
原因はncbファイルの破損っぽい.
http://blogs.yahoo.co.jp/dpdtp652/837997.html 参照
ncbファイルはちなみにintellisenseの情報を保存したファイルっぽい.
ソリューションを1度閉じた後,ソリューションと同じフォルダに存在するプロジェクト名. ncbファイルを削除
再びソリューションを開くと問題が解決している
ジャンル:Visual Studio
コード要素*** が読み取り専用であるため、追加と削除操作は出来ません VS2010編 †
Visual Studio 2010で発生
MFCダイアログボックスにボタンを追加し,イベントハンラを追加しようとしたら発生
原因はインテリセンスの保存されているsdfファイルの模様
ソリューションを1度閉じた後,ソリューションと同じフォルダに存在するソリューション名. sdfファイルを削除
再びソリューションを開くと問題が解決している
また、だいたいのクラスウィザードのエラーはこれ
ジャンル:Visual Studio
プロジェクトにクラスの追加を行うとVisutal Studioがフリーズする †
メニューからクラスの追加操作を行うだけでVisual Studioがフリーズする.
原因はコード要素が読み取り専用.. と類似
ncbファイルを削除すること
ジャンル:Visual Studio
CRとLF †
CRが\rであり,Mac OS(9まで)などで使われていた改行コード
LFが\nであり,Unix系のOSなどで使われている改行コード
WindowsではCR+LFであり,\r\nで表される
コンソール画面が消えない †
OpenCV 2.1 にバージョンアップしてから,ときたま実行したプログラムが終了しないときがある
OpenCV 2.1 + Visual Studio 2003 でコンソールアプリを作成
実行して,正常終了→Visual Studioの画面が実行モードから編集モードに戻る
が,それでもコンソール画面が出たまま
少ない事例だが,今のところOpenCVで生成したウィンドウは消えている
Visual Studioを終了させてもダメ
再起動させようにも,残ったコンソール画面が悪さをして再起動できない.
OpenCV 2.1でウィンドウを生成して,ウィンドウを破棄(cvDestroyWindow)せずにプログラムだけ止めると,発生する模様.
ジャンル:Visual Studio
Visual Studio でコマンドラインアプリをデバッグする際,引数を指定する方法 †
コマンドラインアプリで,引数により挙動を変えるプログラムをよく作る(私は)
ただし,デバッグモードでは,引数なしの状態でしか実行されない
プロジェクト(P)→プロジェクトのプロパティ(P)→デバッグ→コマンド引数という欄に引数を指定できる
Visual Studio 2008 と 2003で最低限確認した.
ウィンドウのレイアウトは違うかも
添付はVisual Studio 2008の画面
ジャンル:Visual Studio
OpenCV のリポジトリにアクセスしようとしたらユーザ名とパスワードを要求された †
ビットリバースとポップカウント †
bit表記した変数(例えば16bitのshort)の中に1がいくつ存在するかをカウントするのがポップカウント
bit表記した変数(例えば16bitのshort)のbitの並びを前後逆にするのがビットリバース
例
10進数 16進数 2進数 ビットリバース ポップカウント 1 0x01 00000001 10000000 1 2 0x02 00000010 01000000 1 3 0x03 00000011 11000000 2 182 0xB6 10110110 01101101 5 88 0x58 01011000 00011010 3
ルックアップテーブルを使うと結構速い。*9 *10 *11
ビット単位で数える/並べ替えると著しく遅い*11 *9 *10
また、マスキングを使った分割統治法もある*12
プリプロセッサ †
C言語の文字コード変換について †
特に限定してないけれど、基本的にSJIS→UTF-8への変換ができるAPIやライブラリを調べてみた。
::WideCharToMultiByte を使う方法 †
iconvを使う方法 †
iconv_t ic = iconv_open( "SJIS" , "UTF-8" ) ;
memcpy( in, utf8, sizeof ( utf8) ) ;
iconv( ic, & in, & in_size, & out, & out_size ) ;
iconv_close( ic) ;
ICUを使う方法 †
std::string内で使える文字列検索関数 †
vector でfindする方法 †
#include <algorithm>
#include <vector>
std:: vector < int> datas;
int needle;
std:: vector < int>:: iterator it = std:: find ( datas.begin ( ) , datas.end ( ) , needle) ;
if ( it == datas.end ( ) ) {
//見つからなかった場合
std
:: cout << "Not Found" << std
:: endl ;
}
'>>' should be '> >' within a nested template argument list †
cannot appear in a constant-expression †
gcc で const の宣言と代入を同時に行うと、エラーになる*30
sleep について †
iostream のフォーマット指定子 †
typedef の順序 †
いつも混乱する*33
typdef int MyType;
<< operator のオーバーロード †
<< operator をオーバーロードしたら、error LNK2005 リンクエラーが発生した。*34
宣言と実装をヘッダとCPPで分ける必要がある。
getopt を使おう †
すべてのプログラマが読むべき記事10選 †
クラスのoperatorを定義するときの戻り値の型 †
実験した上でまとめてるサイト*40
代入演算
foo& foo::operator = (const foo&);
四則演算
const foo foo::operator + (const foo&);
四則演算と代入
foo& foo::operator += (const foo&);
比較演算
bool foo::operator == (const foo&);
などなど
クラスの operator を定義するとき、戻り値の型はどうすべきか *40
実験した上で考察されているので、自分が理解する手助けになった
string †
Visual Studio でcppunitをビルドするお話 †
Sleep関数 †
複数桁数の数字を文字列に変換する †
ある型が定義されているか確認する方法 †
Cコンパイラとプラットフォームを判定する定義済みマクロ †
gcc msvc 64bit (IA64) __ia64__ _M_IA64 64bit (x86_64) __x86_64__ _M_X64 32bit (x86) __i386__ _M_IX86
Cコンパイラのプラットフォーム、コンパイラを判別する定義済みマクロ*47 *48
メジャーなarchitecture/compiler による pre defined macros
Alpha, AMD64, Arm, Arm64, Blackfin, Convex, Epiphany, HP/PA RISC, Intel x86, Intel Itanium IA-64, Motorola 68k, MIPS, PowerPC, Pyramid 9810, RS/6000, SPARC, SuperH, SystemZ, TMS320, TMS470
こんなアーキテクチャあるんだ・・
Pre-defined Compiler Macros / Wiki / Architectures *49
Pre-defined Compiler Macros / Wiki / Compilers *50
ビット操作 †
streamクラスのeof †
Error: use of enum ‘AVCodecID’ without previous declaration †
C++でvectorの参照渡しを省略可能にする方法 †
普通の引数はオプションにすることが可能
void func( int a, int b = 0 ) ;
と宣言されていれば、
func( 1 ) ; // func(1, 0) と等価
func( 1 , 0 ) ; // 上記と同じ挙動
func( 1 , 1 ) ; // いずれもエラーにならない
という呼び方が可能
ただ、引数にvector何かをオプションで渡したいときに悩む
void func( int a, const std:: vector < int>& b = std:: vector < int> ( ) ) ;
こうすれば、bのvectorはオプション扱い
constを付けないと、gccだと叱られる
参考:shnya_mさんはTwitterを使っています: "@uchumik ディフォルト引数取るってことは、 *57
参考:gist:5048103 *58
invalid initialization of non-const reference of type †
Visual Studio では発生しないが、gccで発生するエラー
関数の実引数が一時変数の時は、constを付けないと、エラーになる*59 *60
普通の変数と一時的な変数
int a などは普通の変数
a + 1 の結果もintだが、格納するまでは一時変数
サンプルコード
inline myClass myClass:: clone ( ) const
{
myClass m;
return m;
}
void function1( myClass& before)
{
return ;
}
void function2( const myClass& before)
{
return ;
}
int main( int argc, char ** argv)
{
myClass a = myClass( ) ;
function1( a) ;
function1( a.clone ( ) ) ; // this causes error 'invalid initialization of non-const reference of type'
function2( a) ;
function2( a.clone ( ) ) ;
return 0 ;
}
前述のサンプルコードのうち、2つ目のcall だけがgccでエラーになる*61
Visual Studio では発生しない*62
参考:最近のはまりポイント - 三次元日誌 *59
参考:リリカル☆Lisp開発日記 » Blog Archive » C++の参照を使ってもcall by referenceにはならない *60
how to create a directory using c++ + WINAPI †
get the last character of std::string †
how to get a string which express time information †
use time_t and ostringstream*68
void getTimeString( std:: string & result)
{
time_t now = time( 0 ) ;
tm ltm;
localtime_s( & ltm, & now) ; // get the local time
std:: ostringstream ostr; // use ostringstream to format the time
ostr << ltm.tm_year + 1900 ; // year
ostr << std:: setw ( 2 ) << std:: setfill ( '0' ) << ltm.tm_mon + 1 ; // month
ostr << std:: setw ( 2 ) << std:: setfill ( '0' ) << ltm.tm_mday ; // day
ostr << std:: setw ( 2 ) << std:: setfill ( '0' ) << ltm.tm_hour ; // hour
ostr << std:: setw ( 2 ) << std:: setfill ( '0' ) << ltm.tm_min ; // minute
ostr << std:: setw ( 2 ) << std:: setfill ( '0' ) << ltm.tm_sec ; // second
result = ostr.str ( ) ;
}
itoa was a good function to convert an integer number to a string, but due to security issue, it's no longer standard*69
itoa_s(the alternative of itoa) doesn't convert the format, so it's not useful either*70
if WINAPI is available, use CString *71 , otherwise depend on ostringstream *72