Stdplus.c

C:\home\SVGCats_src\src\Stdplus.c

[目次 | 関数 | マクロ]

目次

関数一覧

マクロ一覧


   1|/*************************************************************************
   2|*  1. <<< 標準ライブラリ拡張 (StdPlus) >>> 
   3|**************************************************************************/
   4|
   5|#include "mixer_precomp.h"  /* Auto precompiled header, Look at mixer-... folder */
   6|
   7|#define  STDLIBS_INCLUDE_STRING_H
   8|#define  STDLIBS_INCLUDE_STDARG_H
   9|#ifdef  USES_MXP_AUTOINC
  10| #include "stdplus.ah"  /* Auto include header, Look at mixer-... folder */
  11|#endif
  12|
  13|#ifndef  STDPLUS_NOT_ERRNO
  14|  #include  <errno.h>
  15|#endif
  16|
  17|
  18|int  StdPlus_chkAdr = 0x00000000;
  19|int  StdPlus_FreeChk_breakID = 0;
  20|
  21|static  void  StdPlus_breakFunc()  {}   /* ここにブレークポイントを張ってください */
  22|
  23| 
  24|/*-----------------------------------------------------------------------*/
  25|/*  2. <<< ◆(StdPlus) 標準ライブラリ拡張 >>> */ 
  26|/*-----------------------------------------------------------------------*/
  27|
  28|int  StdPlus_mallocCount = 0;
  29|
  30| 
  31|/***********************************************************************
  32|*  3. <<< [StdPlus_malloc] 拡張 malloc >>> 
  33|*  4. <<< [StdPlus_malloc_imp] >>>
  34|*【補足】
  35|*・メモリ領域を確保できなかった場合、エラーになります。
  36|*・StdPlus_free と呼出し回数をチェックすることができるようになります。
  37|* (StdPlus_chkFree 関数)
  38|*・StdPlus_malloc StdPlus_free はなるべく直接呼び出さないようにし、
  39|*  STDPLUS_USES_STDNAME を #define して、malloc StdPlus_malloc に
  40|*  書きかえるようにします。さもなければ、StdPlus_malloc 標準ライブラリの
  41|*  free を呼び出すようなことが起きる可能性が出てしまい、呼び出し回数の
  42|*  チェックがおかしくなることがあります。
  43|*・例外処理により確実に free するには次のようにします。
  44|*    Type*  p = NULL;   // NULL で初期化しておく
  45|*    try {
  46|*      p = malloc( 20 );  // try の中で StdPlus_malloc を呼び出す
  47|*       :
  48|*    }
  49|*    finally {    // finally または catch の中で StdPlus_free を呼び出す。
  50|*      free( p );    // StdPlus_free 内部で、NULL ならフリーしない
  51|*    } end_finally;
  52|************************************************************************/
  53|#ifdef  STDPLUS_USES_STDLIB
  54|
  55|#ifndef  STDPLUS_PRINT_NOT_FREE
  56|  void*  StdPlus_malloc( int size )
  57|#else
  58|  void*  StdPlus_malloc_imp( int size, char* file, int line )
  59|#endif
  60|{
  61|  #ifdef  STDPLUS_USES_STDNAME
  62|    #undef  malloc
  63|  #endif
  64|
  65|  void*   p = malloc( size );
  66|
  67|  #ifndef  STDPLUS_PRINT_NOT_FREE
  68|    StdPlus_onMalloc_imp( p, NULL, 0 );
  69|  #else
  70|    StdPlus_onMalloc_imp( p, file, line );
  71|  #endif
  72|
  73|  return  p;
  74|
  75|  #ifdef  STDPLUS_USES_STDNAME
  76|    #define  malloc  StdPlus_malloc
  77|  #endif
  78|}
  79|#endif
  80|
  81| 
  82|/***********************************************************************
  83|*  5. <<< [StdPlus_onCoCreateInstance] ON_CO_CREATE_INSTANCE の関数部 >>> 
  84|************************************************************************/
  85|void  StdPlus_onCoCreateInstance( void* p, int hr, char* file, int line )
  86|{
  87|  if ( hr != 0 )
  88|    { Errors_printf_release( "hr = 0x%08X in %s(%d)", hr, file, line );  error(); }
  89|
  90|  StdPlus_onMalloc_imp( p, file, line );
  91|}
  92| 
  93|/***********************************************************************
  94|*  6. <<< [StdPlus_onMalloc_imp] malloc/new 用・開放チェック >>> 
  95|*【引数】
  96|*  ・void*  p;  オブジェクトのアドレス
  97|*【補足】
  98|*・StdPlus_malloc(にオーバーライドした malloc)を使っているときは、
  99|*  本関数が自動的に呼ばれますが、C++ では、コンストラクタから呼び出す
 100|*  必要があります。
 101|************************************************************************/
 102|#ifdef  STDPLUS_USES_STDLIB
 103|
 104|void  StdPlus_onMalloc_imp( void* p, char* file, int line )
 105|{
 106|  #ifdef  STDPLUS_PRINT_NOT_FREE
 107|    StdPlus_FreeChk_setMalloc( StdPlus_FreeChk_getGlobl(), p, file, line );
 108|  #endif
 109|
 110|  if ( p == NULL )
 111|    error2_0( StdPlus_Err_MallocFailure, "malloc できません" );
 112|  else
 113|    StdPlus_mallocCount ++;
 114|
 115|  /* デバッグ用、malloc した位置を知るため */
 116|  /* 次の free & malloc で同じアドレスを返すことがあるので注意 */
 117|  #ifndef  NDEBUG
 118|    if ( (int)p == StdPlus_chkAdr ) {  /* ここに開放されていないアドレスを記述する(1) */
 119|      StdPlus_breakFunc();
 120|      Errors_printf( "malloc ( %p );", p );
 121|      //COUNT(0)
 122|      //  Errors_break(1);
 123|    }
 124|  #endif
 125|}
 126|
 127|#endif
 128| 
 129|/***********************************************************************
 130|*  7. <<< [StdPlus_free] 拡張 free >>> 
 131|*  8. <<< [StdPlus_free_imp] >>>
 132|*【補足】
 133|*・引数に NULL を指定した場合、何もしません。
 134|*・StdPlus_malloc と呼出し回数をチェックすることができるようになります。
 135|* (StdPlus_chkFree 関数)
 136|*・STDPLUS_PRINT_NOT_FREE を #define すると、free していないアドレスを
 137|*  表示できます。(Errors_chkDefault で)
 138|*・STDPLUS_USES_STDNAME を #define すると、free StdPlus_free に
 139|*  書きかえるようになります。
 140|************************************************************************/
 141|#ifdef  STDPLUS_USES_STDLIB
 142|
 143|#ifndef  STDPLUS_PRINT_NOT_FREE
 144|  void  StdPlus_free( void* p )
 145|#else
 146|  void  StdPlus_free_imp( void* p, char* file, int line )
 147|#endif
 148|{
 149|  #ifdef  STDPLUS_USES_STDNAME
 150|    #undef  free
 151|  #endif
 152|
 153|  if ( p != NULL ) {
 154|    #ifndef  STDPLUS_PRINT_NOT_FREE
 155|      StdPlus_onFree_imp( p, NULL, 0 );
 156|    #else
 157|      StdPlus_onFree_imp( p, file, line );
 158|    #endif
 159|    free( p );
 160|  }
 161|
 162|  #ifdef  STDPLUS_USES_STDNAME
 163|    #define  free  StdPlus_free
 164|  #endif
 165|}
 166|#endif
 167|
 168| 
 169|/***********************************************************************
 170|*  9. <<< [StdPlus_onIUnknownRelease] ON_CO_CREATE_INSTANCE の関数部 >>> 
 171|************************************************************************/
 172|void  StdPlus_onIUnknownRelease( void* p, int hr, char* file, int line )
 173|{
 174|  StdPlus_onFree_imp( p, file, line );
 175|}
 176| 
 177|/***********************************************************************
 178|*  10. <<< [StdPlus_onFree_imp] free/delete 用・開放チェック >>> 
 179|*【引数】
 180|*  ・void*  p;  オブジェクトのアドレス
 181|*【補足】
 182|*・StdPlus_free(にオーバーライドした free)を使っているときは、
 183|*  本関数が自動的に呼ばれますが、C++ では、デストラクタから呼び出す
 184|*  必要があります。
 185|************************************************************************/
 186|#ifdef  STDPLUS_USES_STDLIB
 187|
 188|void  StdPlus_onFree_imp( void* p, char* file, int line )
 189|{
 190|  #ifdef  STDPLUS_PRINT_NOT_FREE
 191|    StdPlus_FreeChk_setFree( StdPlus_FreeChk_getGlobl(), p, file, line );
 192|  #endif
 193|
 194|  /* デバッグ用、free した位置を知るため */
 195|  /* 次の free & malloc で同じアドレスを返すことがあるので注意 */
 196|  #ifndef  NDEBUG
 197|    if ( (int)p == StdPlus_chkAdr )  /* ここに開放されていないアドレスを記述する(2) */
 198|      Errors_printf( "free ( %p );", p );  /* ここにブレークポイントを張る */
 199|  #endif
 200|
 201|  StdPlus_mallocCount --;
 202|}
 203|
 204|#endif
 205| 
 206|/***********************************************************************
 207|*  11. <<< [StdPlus_realloc] 拡張 realloc >>> 
 208|*  12. <<< [StdPlus_realloc_imp] >>>
 209|************************************************************************/
 210|#ifdef  STDPLUS_USES_STDLIB
 211|
 212|#ifndef  STDPLUS_PRINT_NOT_FREE
 213|  void*  StdPlus_realloc( void* p, int size )
 214|#else
 215|  void*  StdPlus_realloc_imp( void* p, int size, char* file, int line )
 216|#endif
 217|{
 218|  #ifdef  STDPLUS_USES_STDNAME
 219|    #undef  realloc
 220|  #endif
 221|
 222|  if ( p != NULL ) {
 223|    #ifndef  STDPLUS_PRINT_NOT_FREE
 224|      StdPlus_onFree_imp( p, NULL, 0 );
 225|    #else
 226|      StdPlus_onFree_imp( p, file, line );
 227|    #endif
 228|  }
 229|
 230|  p = realloc( p, size );
 231|
 232|  #ifndef  STDPLUS_PRINT_NOT_FREE
 233|    StdPlus_onMalloc_imp( p, NULL, 0 );
 234|  #else
 235|    StdPlus_onMalloc_imp( p, file, line );
 236|  #endif
 237|
 238|  return  p;
 239|
 240|
 241|  #ifdef  STDPLUS_USES_STDNAME
 242|    #define  realloc  StdPlus_realloc
 243|  #endif
 244|}
 245|#endif
 246|
 247| 
 248|/***********************************************************************
 249|*  13. <<< [StdPlus_chkMalloc] malloc したアドレスをチェックする >>> 
 250|*【引数】
 251|*  ・void* p1 ...;     malloc したポインタの羅列(最後は StdPlus_End)
 252|*  ・int  返り値;      Errors_NoError StdPlus_Err_MallocFailure
 253|*【例】
 254|*  StdPlus_chkMalloc( ptr, ptr2, StdPlus_End );
 255|*【補足】
 256|*・例外処理と StdPlus_malloc を使用すれば、本関数を使わなくても
 257|*  同じことができます。
 258|*・第1引数以降は malloc したポインタを並べて、最後は StdPlus_End を
 259|*  指定します。
 260|*・指定したポインタの中に1つでも NULL があれば、エラーになります。
 261|*  その際、NULL 以外のポインタを free してからエラーハンドラを呼び出します。
 262|*  エラーハンドラから戻ったら StdPlus_Err_MallocFailure を返します。
 263|************************************************************************/
 264|#ifdef  STDPLUS_USES_STDLIB
 265|int  StdPlus_chkMalloc( void* p1, ... )
 266|{
 267|  va_list  va;
 268|  void*  p;
 269|  bool   err = false;
 270|
 271|  /* NULL が1つでもあるかどうか */
 272|  va_start( va, p1 );
 273|  for (;;) {
 274|    p = va_arg( va, void* );
 275|    if ( p == StdPlus_End )   break;
 276|    if ( p == NULL )  { err = true;  break; }
 277|  }
 278|  va_end( va );
 279|
 280|  /* NULL があれば、NULL 以外を全て free してエラー */
 281|  if ( err ) {
 282|    va_start( va, p1 );
 283|    for (;;) {
 284|      p = va_arg( va, void* );
 285|      if ( p == StdPlus_End )  break;
 286|      if ( p != NULL )  free( p );
 287|    }
 288|    va_end( va );
 289|
 290|    error2_0( StdPlus_Err_MallocFailure, "malloc できませんでした" );
 291|    return  StdPlus_Err_MallocFailure;
 292|  }
 293|  else {
 294|    return  Errors_NoError;
 295|  }
 296|}
 297|#endif
 298|
 299| 
 300|/***********************************************************************
 301|*  14. <<< [StdPlus_chkFree] free した回数をチェックする >>> 
 302|*【補足】
 303|*・ERRORS_FINISHCHK から呼び出されます。
 304|*・通常、プログラムの最後で呼び出します。
 305|*・StdPlus_malloc StdPlus_free の呼出し回数が異なるときは、
 306|*  エラーになります。
 307|************************************************************************/
 308|void  StdPlus_chkFree()
 309|{
 310|  if ( StdPlus_mallocCount != 0 ) {
 311|    #ifdef  STDPLUS_PRINT_NOT_FREE
 312|      StdPlus_FreeChk_printNotFree( StdPlus_FreeChk_getGlobl() );
 313|    #endif
 314|    Errors_printf_release( "malloc free の回数が合いません。(%+d)",
 315|      StdPlus_mallocCount );
 316|  }
 317|}
 318|
 319| 
 320|/*************************************************************************
 321|*  15. <<< [StdPlus_printErrno] errno 変数の値をエラー表示する >>> 
 322|**************************************************************************/
 323|#if  !defined(STDPLUS_NOT_ERRNO) && ( defined(STDPLUS_USES_STDLIB) || defined(USES_FILEX) )
 324|void  StdPlus_printErrno()
 325|{
 326|  char*  s = "Unknown Error";
 327|
 328|  switch ( errno ) {
 329|    case  ECHILD:  s = "ECHILD   子プロセスが存在しない";  break;
 330|    case  EAGAIN:  s = "EAGAIN   これ以上プロセスを生成できない。";  break;
 331|    case  E2BIG:   s = "E2BIG   引数リストが長すぎる";  break;
 332|    case  EACCES:  s = "EACCES   アクセスが拒否された。";  break;
 333|    case  EBADF:   s = "EBADF   不正なファイル番号。";  break;
 334|    case  EDEADLOCK:  s = "EDEADLOCK   リソースのデッドロックが発生する可能性がある。";  break;
 335|    case  EDOM:    s = "EDOM   数値演算関数の引数が関数のドメイン外の値である。";  break;
 336|    case  EEXIST:  s = "EXIST   ファイルが存在する。";  break;
 337|    case  EINVAL:  s = "EINVAL   不正な引数。";  break;
 338|    case  EMFILE:  s = "EMFILE   開いているファイルが多すぎる。";  break;
 339|    case  ENOENT:  s = "ENOENT   ファイルまたはディレクトリがない。";  break;
 340|    case  ENOEXEC: s = "ENOEXEC   実行ファイルのエラー。";  break;
 341|    case  ENOMEM:  s = "ENOMEM   メモリ不足。";  break;
 342|    case  ENOSPC:  s = "ENOSPC   デバイスの空き領域不足。";  break;
 343|    case  ERANGE:  s = "ERANGE   結果が大きすぎる。";  break;
 344|    case  EXDEV:   s = "EXDEV   デバイス間リンク。";  break;
 345|  }
 346|
 347|  Errors_errPrintf( "errno = %d : %s", errno, s );
 348|}
 349|#endif
 350|
 351| 
 352|/**************************************************************************
 353|*  16. <<< [StdPlus_itoa] 数値を文字列に変換する >>> 
 354|*【引数】
 355|*  ・int    value;    数値
 356|*  ・char*  string;   文字列を格納する領域の先頭アドレス
 357|*  ・int    radix;    進数
 358|*  ・char*  返り値;   string と同じ
 359|*【補足】
 360|*・16進数などのアルファベット文字は大文字になります。
 361|*・標準ライブラリ_itoa は存在しません。
 362|***************************************************************************/
 363|char*  StdPlus_itoa( int value, char* string, int radix )
 364|{
 365|  char*  p = string;
 366|  char*  pp;
 367|  int    m;
 368|  int    bMinus;
 369|
 370|  ASSERT( 1 <= radix && radix <= 36);
 371|
 372|  bMinus = (value < 0 );
 373|  if ( bMinus )  value = -value;
 374|
 375|  /* 下の桁から数字を格納する */
 376|  if ( radix <= 10 ) {
 377|    do {
 378|      m = value % radix;
 379|      *p = m + '0';
 380|      value /= radix;
 381|      p++;
 382|    } while ( value != 0 );
 383|  }
 384|  else {
 385|    do {
 386|      m = value % radix;
 387|      *p = m + ( m < 10 ?  '0' : 'A'-10 );
 388|      value /= radix;
 389|      p++;
 390|    } while ( value != 0 );
 391|  }
 392|  if ( bMinus ) {
 393|    *p = '-';  p++;
 394|  }
 395|  *p = '\0';
 396|
 397|  /* 下の桁から上の桁を入れ替える */
 398|  pp = string;  p--;
 399|  while ( pp < p ) {
 400|    m = *pp;  *pp = *p;  *p = m;
 401|    pp++;  p--;
 402|  }
 403|
 404|  return  string;
 405|}
 406|
 407|
 408|
 409| 
 410|/**************************************************************************
 411|*  17. <<< [StdPlus_utoa] 数値を文字列に変換する >>> 
 412|*【引数】
 413|*  ・unsigned int   value;    数値
 414|*  ・char*          string;   文字列を格納する領域の先頭アドレス
 415|*  ・int            radix;    進数
 416|*  ・char*          返り値;   string と同じ
 417|*【補足】
 418|*・16進数などのアルファベット文字は大文字になります。
 419|*・標準ライブラリ_utoa は存在しません。
 420|***************************************************************************/
 421|char*  StdPlus_utoa( unsigned value, char* string, int radix )
 422|{
 423|  char*  p = string;
 424|  char*  pp;
 425|  int    m;
 426|
 427|  ASSERT( 1 <= radix && radix <= 36);
 428|
 429|  /* 下の桁から数字を格納する */
 430|  if ( radix <= 10 ) {
 431|    do {
 432|      m = value % radix;
 433|      *p = m + '0';
 434|      value /= radix;
 435|      p++;
 436|    } while ( value != 0 );
 437|  }
 438|  else {
 439|    do {
 440|      m = value % radix;
 441|      *p = m + ( m < 10 ?  '0' : 'A'-10 );
 442|      value /= radix;
 443|      p++;
 444|    } while ( value != 0 );
 445|  }
 446|  *p = '\0';
 447|
 448|  /* 下の桁から上の桁を入れ替える */
 449|  pp = string;  p--;
 450|  while ( pp < p ) {
 451|    m = *pp;  *pp = *p;  *p = m;
 452|    pp++;  p--;
 453|  }
 454|
 455|  return  string;
 456|}
 457|
 458|
 459|
 460| 
 461|/**************************************************************************
 462|*  18. <<< [StdPlus_xtoi] 16進数文字列を数値に変換する >>> 
 463|*【引数】
 464|*  ・char*  hex;   16進数文字列
 465|*  ・int  返り値;  数値
 466|***************************************************************************/
 467|int  StdPlus_xtoi( char* hex )
 468|{
 469|  char*  s = hex;
 470|  int    c;
 471|  int    num = 0;
 472|
 473|  while ( *s != '\0' ) {
 474|    c = *s;
 475|    if ( c >= '0' && c < '9' )       num = num * 16 + (c - '0');
 476|    else if ( c >= 'A' && c < 'F' )  num = num * 16 + (c - 'A' + 10);
 477|    else if ( c >= 'a' && c < 'f' )  num = num * 16 + (c - 'a' + 10);
 478|    else  return  num;
 479|    s++;
 480|  }
 481|  return  num;
 482|}
 483|
 484|
 485| 
 486|/***********************************************************************
 487|*  19. <<< [StdPlus_inputS] 文字列の初期値の入力 >>> 
 488|*【引数】
 489|*  ・char*  msg;     プロンプト・メッセージ
 490|*  ・char*  out;     入力結果(出力)
 491|*  ・int  out_size;  out のサイズ
 492|*  ・char*  def;     デフォルト値
 493|*【補足】
 494|*・sdvex を使用しています。
 495|*・BS キーで入力しなおします。
 496|*・リターンキーのみで、デフォルト値が入力結果に格納されます。
 497|************************************************************************/
 498|#ifdef  USES_SDVEX
 499|void  StdPlus_inputS( const char* msg, char* out, int out_size, const char* def )
 500|{
 501|  int   i = 0;
 502|  int   c;
 503|  printf( "%s", msg );
 504|
 505|  for (;;) {
 506|    c = inkey();
 507|    if ( c == 0 )  continue;
 508|    else if ( c == 13 )  break;
 509|    #ifdef  USES_ERRORS
 510|    else if ( c == 0x1B )
 511|      error2_0( 0, "ユーザ・ブレイク" );
 512|    #endif
 513|    else if ( c == 8 ) {
 514|      printf( "\n%s", msg );
 515|      i = 0;
 516|    }
 517|    else {
 518|      if ( i < out_size - 1 ) {
 519|        printf( "%c", c );
 520|        out[i] = c;
 521|        i++;
 522|      }
 523|    }
 524|  }
 525|
 526|  /* 値を設定する */
 527|  if ( i == 0 ) {
 528|    strcpy( out, def );
 529|  }
 530|  else {
 531|    out[i] = '\0';
 532|  }
 533|  printf( "\n" );
 534|}
 535|#endif
 536|
 537|
 538| 
 539|/***********************************************************************
 540|*  20. <<< [StdPlus_inputX] 16進数の初期値の入力 >>> 
 541|************************************************************************/
 542|#ifdef  USES_SDVEX
 543|int  StdPlus_inputX( const char* msg, int def )
 544|{
 545|  enum { buf_size = 9 };
 546|  char  buf[buf_size];
 547|
 548|  StdPlus_inputS( msg, buf, buf_size, "" );
 549|
 550|  if ( buf[0] == '\0' )  return  def;
 551|  else  return  _xtoi( buf );
 552|}
 553|#endif
 554|
 555|
 556| 
 557|/*-----------------------------------------------------------------------*/
 558|/*  21. <<< ◆(StdPlus_FreeChk) free のし忘れを追跡するツール >>> */ 
 559|/*-----------------------------------------------------------------------*/
 560|
 561|#ifndef  ERRORS_CUT_DEBUT_TOOL
 562|#ifdef  STDPLUS_PRINT_NOT_FREE
 563|
 564|bool  StdPlus_FreeChk_inited = false;
 565|StdPlus_FreeChk   StdPlus_FreeChk_globl;
 566| 
 567|/***********************************************************************
 568|*  22. <<< [StdPlus_FreeChk_init] 初期化する >>> 
 569|*【補足】
 570|*・→StdPlus_FreeChk クラスの補足
 571|************************************************************************/
 572|void  StdPlus_FreeChk_init( StdPlus_FreeChk* m )
 573|{
 574|  StdPlus_FreeChkE*  p;
 575|  StdPlus_FreeChkE*  p_over = m->rec + StdPlus_FreeChk_Depth;
 576|
 577|  StdPlus_FreeChk_inited = true;
 578|
 579|  Errors_printf_release( "free し忘れの追跡ツールを起動します。" );
 580|
 581|  m->count = 0;
 582|  for ( p = m->rec; p < p_over; p++ ) {
 583|    p->adr = NULL;
 584|  }
 585|}
 586|
 587|
 588| 
 589|/***********************************************************************
 590|*  23. <<< [StdPlus_FreeChk_setMalloc] malloc に関する記録をする >>> 
 591|*【内部補足】
 592|*・StdPlus_malloc の内部で呼び出されます。
 593|************************************************************************/
 594|void  StdPlus_FreeChk_setMalloc( StdPlus_FreeChk* m, void* adr, char* file, int line )
 595|{
 596|  StdPlus_FreeChkE*  p;
 597|  StdPlus_FreeChkE*  p_over;
 598|  m->count ++;
 599|  if ( StdPlus_FreeChk_breakID == m->count )  StdPlus_breakFunc();
 600|
 601|  if ( ! StdPlus_FreeChk_inited ) {
 602|    StdPlus_FreeChk_init( &StdPlus_FreeChk_globl );
 603|    //    Errors_printf( "StdPlus_FreeChk_init を呼び出してください" );
 604|    //    error();
 605|  }
 606|  p_over = m->rec + StdPlus_FreeChk_Depth;
 607|
 608|  for ( p = m->rec; p < p_over; p++ ) {
 609|    if ( p->adr == NULL ) {
 610|      #if  ERRORS_DEBUG_FALSE
 611|        Errors_printf( "malloc (%p) in %s(%d)", adr, file, line );
 612|      #endif
 613|      p->id = m->count;  p->adr = adr;  p->file = file;  p->line = line;
 614|      return;
 615|    }
 616|  }
 617|  error2_0( StdPlus_Err_CannotContinueCheck,
 618|    "StdPlus_FreeChk_Depth を大きくしてください。" );
 619|}
 620|
 621|
 622| 
 623|/***********************************************************************
 624|*  24. <<< [StdPlus_FreeChk_setFree] free に関する記録をする >>> 
 625|*【内部補足】
 626|*・StdPlus_free の内部で呼び出されます。
 627|************************************************************************/
 628|void  StdPlus_FreeChk_setFree( StdPlus_FreeChk* m, void* adr, char* file, int line )
 629|{
 630|  StdPlus_FreeChkE*  p;
 631|  StdPlus_FreeChkE*  p_over;
 632|
 633|  if ( ! StdPlus_FreeChk_inited ) {
 634|    StdPlus_FreeChk_init( &StdPlus_FreeChk_globl );
 635|    //Errors_printf( "StdPlus_FreeChk_init を呼び出してください" );
 636|    //error();
 637|  }
 638|  p_over = m->rec + StdPlus_FreeChk_Depth;
 639|
 640|  if ( adr == NULL ) {
 641|    error2_2( StdPlus_Err_NullFree, "NULL がフリーされました in %s(%d)", file, line );
 642|  }
 643|
 644|  for ( p = m->rec; p < p_over; p++ ) {
 645|    if ( p->adr == adr ) {
 646|      p->adr = NULL;
 647|      return;
 648|    }
 649|  }
 650|  error();
 651|}
 652| 
 653|/***********************************************************************
 654|*  25. <<< [StdPlus_FreeChk_printNotFree] free していないアドレスを表示する >>> 
 655|************************************************************************/
 656|void  StdPlus_FreeChk_printNotFree( StdPlus_FreeChk* m )
 657|{
 658|  StdPlus_FreeChkE*  p;
 659|  StdPlus_FreeChkE*  p_over = m->rec + StdPlus_FreeChk_Depth;
 660|  int  count = 0;
 661|
 662|  if ( ! StdPlus_FreeChk_inited ) {
 663|    Errors_printf( "StdPlus_FreeChk_init を呼び出してください" );
 664|    error();
 665|  }
 666|
 667|  Errors_printf( "StdPlus_FreeChk result: Not free adress is ..." );
 668|  for ( p = m->rec; p < p_over; p++ ) {
 669|    if ( p->adr != NULL ) {
 670|      Errors_printf( "id = %d, adr = %p in %s(%d)", p->id, p->adr, p->file, p->line );
 671|      count++;
 672|      if ( count == 100 ) {
 673|        Errors_printf( "100件を超えたので続きの表示を中止します。" );
 674|        break;
 675|      }
 676|    }
 677|  }
 678|  Errors_printf( "StdPlus_FreeChk Done." );
 679|}
 680| 
 681|#endif 
 682|#endif
 683| 
 684|