a24_acl1T_doc01
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* acl1Tinyのドキュメント #1
-(by [[K]], 2024.09.20)
** (0)
-このドキュメントを書いている時点での、acl1Tinyのファイル...
--https://essen.osask.jp/files/acl1Tiny_20240923.7z (7.9KB)
--https://essen.osask.jp/files/acl1Tiny_20240920.7z (8.0KB)
--https://essen.osask.jp/files/acl1Tiny_20240920.zip (11....
-つまり、以下のようなことが、たった7.9KBで実現できてしま...
--[1]C言語でもメモリリークしないプログラムが書けるように...
--[2]C言語でもガーベージコレクションのある言語みたいにfre...
--[3]二重freeとかのバグを根絶できる。
--[4]C++のテンプレートみたいなことがC言語でもできる(C++...
--[5]qsortより速いソートが使える。
--[6]malloc/freeの高速化もある。
-いやまあいろいろ及ばないところもあるかもしれないけど、7....
-acl1Tinyの全体像は[[a24_programs]]で分かります、たぶん。
** (1) メモリリーク検出
-acl1Tinyには、メモリリーク検出機能があります。コンパイル...
-ADbgLvを未定義にするか、0で定義しておけば、メモリリーク...
-簡単な実験をしてみます。もちろんADbgLvを1以上にしてコン...
#include <acl1Tiny.c>
int main()
{
char *p = AM_alc(am0, 0, 1234); // char *p = mal...
AM_dst(am0); // ←この記述で、am0は閉じられる(デスト...
return 0;
}
// am0 : デフォルトで用意されるメモリアロケータ.
[実行結果]
AM_dst(): error(n=1, total=1234)
-このように、未解放のメモリブロックが実行時に検出されまし...
-メモリアロケータからメモリアロケータを作ることができます...
#include <acl1Tiny.c>
int main()
{
AM *child = AM1_opn(0, am0); // AM1型のメモリアロケ...
char *p = AM_alc(child, 0, 1234); // char *p = m...
AM_dst(am0); // ←この記述で、am0は閉じられる(デスト...
return 0;
}
[実行結果]
AM_dst(): error(n=2, total=1314)
-今回は2つのメモリブロックが未解放だと指摘されました。こ...
-ということで、リークを見逃すことはありませんでした。
** (2) 自動解放のテスト
-acl1Tinyでは、自動解放をサポートしています。 自動解...
#include <acl1Tiny.c>
int main()
{
AM *child = AM1_opn(1, am0); // AM1型のメモリアロケ...
char *p = AM_alc(child, 1, 1234); // char *p = m...
AM_dst(am0); // ←この記述で、am0は閉じられる(デスト...
return 0;
}
[実行結果]
(エラーがないので何も出力されません)
-今回は自動解放フラグを1にして、childやpを作りました。こ...
-そして、am0はdstされると自身をreleaseしますし、childもds...
-結局こういう流れになります。 am0.dst → am0.release → chi...
-明示的なfreeを一切書かなくてもメモリリークしないなんて、...
-なおこの自動解放の仕組みは Objective-C の Autorelease を...
-では、pの自動解放だけをOFFにしたらどうなるでしょうか。や...
#include <acl1Tiny.c>
int main()
{
AM *child = AM1_opn(1, am0); // AM1型のメモリアロケ...
char *p = AM_alc(child, 0, 1234); // char *p = m...
AM_dst(am0); // ←この記述で、am0は閉じられる(デスト...
return 0;
}
[実行結果]
AM_dst(): error(n=1, total=1234)
-このようにpが未解放であることを教えてくれます。先ほどの...
-ところで、このエラーはam0が出しているのでしょうか?それ...
#include <acl1Tiny.c>
int main()
{
AM *child = AM1_opn(1, am0); // AM1型のメモリアロケ...
char *p = AM_alc(child, 0, 1234); // char *p = m...
AM_dbgSetNam(am0, "am0"); // アロケータにデバッグ用...
AM_dbgSetNam(child, "child");
AM_dst(am0); // ←この記述で、am0は閉じられる(デスト...
return 0;
}
[実行結果]
AM_dst(child): error(n=1, total=1234)
-このようにリークを検出したアロケータの名前が表示されるよ...
-なお、 AM_dbgSetNam()は、ADbgLv=0のときは自動で空っぽの...
-この「オブジェクトの名前」の情報は、AM構造体の中には含ま...
** (3) AM1Dbgについて
-malloc/freeの深刻なバグとしては、mallocで得たわけではな...
-acl1の場合ですと、これに加えてfreeするときにmallocのとき...
-これをガードするには、mallocのたびにポインタとサイズを記...
-ということで、チェックだけをするメモリアロケータ「AM1Dbg...
#define ADgbLv 5 // 以下のプログラムは非常に危険なので...
#include <acl1Tiny.c>
#include <AM1Dbg.c>
int main()
{
AM *am1d = AM1Dbg_opn(1, am0, AMapSim11_opn(1, am0));
AM_fre(am1d, (void *) (AInt) 0x01234567, 1234);
AM_dst(am0);
return 0;
}
[実行結果]
AM1Dbg_fre(): error: sz != -1
-これはポインタが登録されていないときに出るエラーです。う...
-今度はわざとサイズを間違えて解放してみます。
#define ADgbLv 5 // 以下のプログラムは非常に危険なので...
#include <acl1Tiny.c>
#include <AM1Dbg.c>
int main()
{
AM *am1d = AM1Dbg_opn(1, am0, AMapSim11_opn(1, am0));
void *p = AM_alc(am1d, 0, 1234);
AM_fre(am1d, p, 1233);
AM_dst(am0);
return 0;
}
[実行結果]
AM1Dbg_fre(): error: sz != 1234
-これはサイズが確保した時と一致していないことを表していま...
-誤って自動解放オブジェクトを手動で解放した場合はどうでし...
#include <acl1Tiny.c>
#include <AM1Dbg.c>
int main()
{
AM *am1d = AM1Dbg_opn(1, am0, AMapSim11_opn(1, am0));
void *p = AM_alc(am1d, 1, 1234);
AM_fre(am1d, p, 1234); // 誤って自動解放オブジェクト...
AM_dst(am0);
return 0;
}
[実行結果]
AM1Dbg_fre(): error: sz != -1
-手動解放で消えた後に、自動解放で消そうとして、ポインタが...
-どのケースも解放処理が行われる前にエラーで止まっているの...
** (4)
-C言語は生ポインタが簡単に扱えてしまうから、メモリリーク...
-それはとても重要なアプローチですが、一方であえてC言語に...
** (5) おまけ
-sprintf()はいろんなことが簡単にできて便利なのですが、以...
--関数の戻り値が文字数であって、文字列のポインタじゃない。
--sprintfの結果を入れるためのメモリを呼び出し元が用意しな...
-これを解消したのが、 AM_spf() です。メモリは強制的に自動...
-これを使うと以下のようなプログラムを作れます、もちろんメ...
-我ながら、おもしろいなーと思います。
#include <acl1Tiny.c>
int main()
{
char *s = ""; int i;
for (i = 0; i < 10; i++)
s = AM_spf(am0, "%s %d", s, i); // s = my_...
puts(s);
AM_dst(am0);
return 0;
}
[実行結果]
0 1 2 3 4 5 6 7 8 9
** (6) さらに
-acl1Tinyには、qsortよりも速いクイックソートや、C言語でC+...
--[[a24_aQSort]] → まずは (4) ベンチマーク を見てみてくだ...
--[[a24_acpp0]]
終了行:
* acl1Tinyのドキュメント #1
-(by [[K]], 2024.09.20)
** (0)
-このドキュメントを書いている時点での、acl1Tinyのファイル...
--https://essen.osask.jp/files/acl1Tiny_20240923.7z (7.9KB)
--https://essen.osask.jp/files/acl1Tiny_20240920.7z (8.0KB)
--https://essen.osask.jp/files/acl1Tiny_20240920.zip (11....
-つまり、以下のようなことが、たった7.9KBで実現できてしま...
--[1]C言語でもメモリリークしないプログラムが書けるように...
--[2]C言語でもガーベージコレクションのある言語みたいにfre...
--[3]二重freeとかのバグを根絶できる。
--[4]C++のテンプレートみたいなことがC言語でもできる(C++...
--[5]qsortより速いソートが使える。
--[6]malloc/freeの高速化もある。
-いやまあいろいろ及ばないところもあるかもしれないけど、7....
-acl1Tinyの全体像は[[a24_programs]]で分かります、たぶん。
** (1) メモリリーク検出
-acl1Tinyには、メモリリーク検出機能があります。コンパイル...
-ADbgLvを未定義にするか、0で定義しておけば、メモリリーク...
-簡単な実験をしてみます。もちろんADbgLvを1以上にしてコン...
#include <acl1Tiny.c>
int main()
{
char *p = AM_alc(am0, 0, 1234); // char *p = mal...
AM_dst(am0); // ←この記述で、am0は閉じられる(デスト...
return 0;
}
// am0 : デフォルトで用意されるメモリアロケータ.
[実行結果]
AM_dst(): error(n=1, total=1234)
-このように、未解放のメモリブロックが実行時に検出されまし...
-メモリアロケータからメモリアロケータを作ることができます...
#include <acl1Tiny.c>
int main()
{
AM *child = AM1_opn(0, am0); // AM1型のメモリアロケ...
char *p = AM_alc(child, 0, 1234); // char *p = m...
AM_dst(am0); // ←この記述で、am0は閉じられる(デスト...
return 0;
}
[実行結果]
AM_dst(): error(n=2, total=1314)
-今回は2つのメモリブロックが未解放だと指摘されました。こ...
-ということで、リークを見逃すことはありませんでした。
** (2) 自動解放のテスト
-acl1Tinyでは、自動解放をサポートしています。 自動解...
#include <acl1Tiny.c>
int main()
{
AM *child = AM1_opn(1, am0); // AM1型のメモリアロケ...
char *p = AM_alc(child, 1, 1234); // char *p = m...
AM_dst(am0); // ←この記述で、am0は閉じられる(デスト...
return 0;
}
[実行結果]
(エラーがないので何も出力されません)
-今回は自動解放フラグを1にして、childやpを作りました。こ...
-そして、am0はdstされると自身をreleaseしますし、childもds...
-結局こういう流れになります。 am0.dst → am0.release → chi...
-明示的なfreeを一切書かなくてもメモリリークしないなんて、...
-なおこの自動解放の仕組みは Objective-C の Autorelease を...
-では、pの自動解放だけをOFFにしたらどうなるでしょうか。や...
#include <acl1Tiny.c>
int main()
{
AM *child = AM1_opn(1, am0); // AM1型のメモリアロケ...
char *p = AM_alc(child, 0, 1234); // char *p = m...
AM_dst(am0); // ←この記述で、am0は閉じられる(デスト...
return 0;
}
[実行結果]
AM_dst(): error(n=1, total=1234)
-このようにpが未解放であることを教えてくれます。先ほどの...
-ところで、このエラーはam0が出しているのでしょうか?それ...
#include <acl1Tiny.c>
int main()
{
AM *child = AM1_opn(1, am0); // AM1型のメモリアロケ...
char *p = AM_alc(child, 0, 1234); // char *p = m...
AM_dbgSetNam(am0, "am0"); // アロケータにデバッグ用...
AM_dbgSetNam(child, "child");
AM_dst(am0); // ←この記述で、am0は閉じられる(デスト...
return 0;
}
[実行結果]
AM_dst(child): error(n=1, total=1234)
-このようにリークを検出したアロケータの名前が表示されるよ...
-なお、 AM_dbgSetNam()は、ADbgLv=0のときは自動で空っぽの...
-この「オブジェクトの名前」の情報は、AM構造体の中には含ま...
** (3) AM1Dbgについて
-malloc/freeの深刻なバグとしては、mallocで得たわけではな...
-acl1の場合ですと、これに加えてfreeするときにmallocのとき...
-これをガードするには、mallocのたびにポインタとサイズを記...
-ということで、チェックだけをするメモリアロケータ「AM1Dbg...
#define ADgbLv 5 // 以下のプログラムは非常に危険なので...
#include <acl1Tiny.c>
#include <AM1Dbg.c>
int main()
{
AM *am1d = AM1Dbg_opn(1, am0, AMapSim11_opn(1, am0));
AM_fre(am1d, (void *) (AInt) 0x01234567, 1234);
AM_dst(am0);
return 0;
}
[実行結果]
AM1Dbg_fre(): error: sz != -1
-これはポインタが登録されていないときに出るエラーです。う...
-今度はわざとサイズを間違えて解放してみます。
#define ADgbLv 5 // 以下のプログラムは非常に危険なので...
#include <acl1Tiny.c>
#include <AM1Dbg.c>
int main()
{
AM *am1d = AM1Dbg_opn(1, am0, AMapSim11_opn(1, am0));
void *p = AM_alc(am1d, 0, 1234);
AM_fre(am1d, p, 1233);
AM_dst(am0);
return 0;
}
[実行結果]
AM1Dbg_fre(): error: sz != 1234
-これはサイズが確保した時と一致していないことを表していま...
-誤って自動解放オブジェクトを手動で解放した場合はどうでし...
#include <acl1Tiny.c>
#include <AM1Dbg.c>
int main()
{
AM *am1d = AM1Dbg_opn(1, am0, AMapSim11_opn(1, am0));
void *p = AM_alc(am1d, 1, 1234);
AM_fre(am1d, p, 1234); // 誤って自動解放オブジェクト...
AM_dst(am0);
return 0;
}
[実行結果]
AM1Dbg_fre(): error: sz != -1
-手動解放で消えた後に、自動解放で消そうとして、ポインタが...
-どのケースも解放処理が行われる前にエラーで止まっているの...
** (4)
-C言語は生ポインタが簡単に扱えてしまうから、メモリリーク...
-それはとても重要なアプローチですが、一方であえてC言語に...
** (5) おまけ
-sprintf()はいろんなことが簡単にできて便利なのですが、以...
--関数の戻り値が文字数であって、文字列のポインタじゃない。
--sprintfの結果を入れるためのメモリを呼び出し元が用意しな...
-これを解消したのが、 AM_spf() です。メモリは強制的に自動...
-これを使うと以下のようなプログラムを作れます、もちろんメ...
-我ながら、おもしろいなーと思います。
#include <acl1Tiny.c>
int main()
{
char *s = ""; int i;
for (i = 0; i < 10; i++)
s = AM_spf(am0, "%s %d", s, i); // s = my_...
puts(s);
AM_dst(am0);
return 0;
}
[実行結果]
0 1 2 3 4 5 6 7 8 9
** (6) さらに
-acl1Tinyには、qsortよりも速いクイックソートや、C言語でC+...
--[[a24_aQSort]] → まずは (4) ベンチマーク を見てみてくだ...
--[[a24_acpp0]]
ページ名: