SSブログ

引数でポインタを変更しないことを明示するには? [C/C++]

C++で関数の引数にポインタを渡すとき、その渡された関数内でポインタの指しているデータ、または、ポインタを変更しないことを明示したい。

これは const を用いれば可能だ。 「ポインタの指しているデータ、または、ポインタを変更しないこと」というのは、言葉だと分かりにくいけど、サンプルコードを見れば分かりやすい。

//example 1
int toge(const int* p)
{
*p = 22; // NG
p = new int(100); // OK
}

int toge(int* const p)
{
*p = 22; // OK
p = new int(100); // NG
}

int toge(const int* const p)
{
*p = 22; // NG
p = new int(100); // NG
}
ちなみに const int* const p であっても、delete は有効らしい。すなわち次のようになる。
void example1Const(const int* const p)
{
delete p; // OK
}
ということは、関数の引数に何かのインスタンスを渡したら、いつの間にか delete されてしまうことがあり得ると言うことですね。怖いねぇ。
タグ:C++ programming

C++/C のデバッグとプロファイルのメモ [C/C++]

C++/C で作成したアプリケーションのデバッグとプロファイルのメモ。

OCXのコントロールの登録

VC6 で OCX のデバッグをしたい。開いているプロジェクトがその OCX で、デバッグセッションの実行可能ファイルが OCX のクライアントアプリケーションだったとする。この場合であっても、OCX をビルドしたらその都度、「コントロールの登録」を行わなければならない。

gprof

gcc/g++ で -pg オプションを付けてコンパイルする。make コマンドを使う場合は Makefile の CFLAGS,LDFLAGS の両方に -pg オプションを付ける必要がある。


マクロ展開後のコードを出力するには? [C/C++]

C/C++ のデバッグ関係のメモ。

マクロ展開後のコードを出力するには?

gcc -E hoge.c

assertを無効にするには?

#define NDEBUG
#include <assert.h>

とする。

ちなみに、

(static_cast<void>  (0)) ;

に置換された。

segmentation fault したときに core を生成させるには?

プログラムが異常終了した場合、 Segmantation falt する。しかし、 core dumped しない環境がある。これは、core の出力が制限されている可能性がある。

ulimit -c unlimited

とすると、core が全て出力される。大きくなりすぎるで、適当に容量制限を付けても良い。 0 になっていると core が出力されない。

gdb

gcc で -g,-ggdb オプションを CFLAGS につけてコンパイルする。

参考文献


タグ:C linux C++ gcc Debug

C/C++ でメモリ関連のバグを調べるには? [C/C++]

C/C++ でメモリ関連のバグを調べるには、Valgrind が使用できそうだ。

Valgrind はメモリとスレッドに関するバグを検出するデバッガである。Valgrind Home では、

Valgrind is an award-winning instrumentation framework for building dynamic analysis tools. There are Valgrind tools that can automatically detect many memory management and threading bugs, and profile your programs in detail. You can also use Valgrind to build new tools. 

と紹介されている。 私はメモリに関するバグを調べたくて使ったことはあるが、スレッド関連のバグを調べるために使用したと経験は今のところ無い。

Valgrind の仕組みは Valgrind によると次のようになっているらしい。

Your program is then run on a synthetic CPU provided by the Valgrind core. As new code is executed for the first time, the core hands the code to the selected tool. The tool adds its own instrumentation code to this and hands the result back to the core, which coordinates the continued execution of this instrumented code.

つまり、デバッグされるプログラムは Valgrind が提供する仮想的な CPU 上で動作すると言うことかな?

※以下、古い話なので、最新の Valgrind には該当しない場合がある。

@@ unlikely looking definition in unparsed remains ";"

と出力されるときは、Valgrind を コンパイルした g++ のバージョンと Valgrind に実行させるプログラムをコンパイルした g++ のバージョンが異なる可能性がある。というか、私はそれにはまった過去が...。どちらも g++ は3.3.0 以上を用いた方が良いと思う。

と書いたが、http://sourceforge.net/mailarchive/forum.php?forum_id=32038&max_rows=25&style=nested&viewmonth=200409 に2004-09-30 13:06 時点の reply で

    Those errors can safely be ignored - they are fixed in the CVS code.

だそうな。Valgrind の ver. は 2.2.0。 詳しくは、該当スレッド参照。

また、STL(stringを含む)を用いたプログラムの場合、プログラムにバグが無くても

==19482== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 1)
==19482== malloc/free: in use at exit: 1280 bytes in 1 blocks.
==19482== malloc/free: 1 allocs, 0 frees, 1280 bytes allocated.
==19482== For counts of detected errors, rerun with: -v
==19482== searching for pointers to 1 not-freed blocks.
==19482== checked 1873888 bytes.
==19482==
==19482== LEAK SUMMARY:
==19482==    definitely lost: 0 bytes in 0 blocks.
==19482==    possibly lost:   0 bytes in 0 blocks.
==19482==    still reachable: 1280 bytes in 1 blocks.
==19482==         suppressed: 0 bytes in 0 blocks.
==19482== Reachable blocks (those to which a pointer was found) are not shown.
==19482== To see them, rerun with: --show-reachable=yes

と alloc に対して free が一致しないことがある。これは g++ 2.9.5 の場合は g++ に -D__USE_MALLOC オプションをつけて試すと良いらしい。ここら辺も、古い話。最新を追いかけていないので、もしかすると修正されているかもしれない。

※以上、古い話おしまい。最新の Valgrind には該当しないかもしれない。

Valdgind はもともと http://valgrind.kde.org/ で公開されていたんだけど、 http://valgrind.org/ に移動したらしい。


この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。