  C++ Programming HOW-TO

  Al Dev (Alavoor Vasudevan)        alavoor@yahoo.com
  v5.0, 4 9  2000
   ,  ö
  2000 6 15

    C++ ޸  ϴ   ٷ C++
  ùٸ α׷ Ҽ ֵ  ְ Ѵ.     
  ü - , MS DOS,  Ų,  95/NT, OS/2, IBM
  ü, VMS, Novell Netware, н   (ֶ󸮽, HPUX,
  AIX, SCO, Sinix, BSC..), ׸ "C++" Ϸ ϴ  ٸ
  ü (ٽ    ϴ   ü̶
    ִ)-  ɼ ִ.
  ______________________________________________________________________

  

  1. 
     1.1  C++ Ϸ  
     1.2 "C"  ΰ "C++"  ΰ ƴϸ ڹٸ ΰ?

  2. ٿε mychar AID CDATA Download mychar(LABEL)LABEL
  3. mychar class 
     3.1 ڵ
     3.2 Լ
     3.3 Ÿ Լ

  4. C++ Zap (Delete) ɾ AID CDATA zap(LABEL)LABEL
  5. my_malloc  my_free  AID CDATA my_malloc(LABEL)LABEL
  6. Debug ȭϵ
  7. C++ Online 
     7.1 C++ Ʃ͸
     7.2 C++ ڵ ǥ
     7.3 C++  ۷
     7.4 C++  ׷

  8. ޸ 
  9.  URL
  10.   ٸ 
  11. ۱
  12. ÷ A example_mychar.cpp  AID CDATA Appendix A(LABEL)LABEL
  13. ÷ B mychar.h  AID CDATA Appendix B(LABEL)LABEL
  14. ÷ C mychar.cpp AID CDATA Appendix C(LABEL)LABEL
  15. ÷ D my_malloc.cpp  AID CDATA Appendix D(LABEL)LABEL
  16. ÷ E my_malloc.h  AID CDATA Appendix E(LABEL)LABEL
  17. ÷ F debug.h AID CDATA Appendix F(LABEL)LABEL
  18. ÷ G debug.cpp AID CDATA Appendix G(LABEL)LABEL
  19. ÷ H Makefile AID CDATA Appendix H(LABEL)LABEL

  ______________________________________________________________________

  1.  

  C++   θ ̴ ̰,  ڹ   
  Ⱓ  ̴.  C++  ſ   ڹٺ 20 30
    ȴ. ڹٴ "virtual engine" ۵Ǵ 
  (interpreted)̱⶧ ſ  ȴ. ڹٿ ޸ 
  ڵ̶ α׷ӵ ޸ ̼ (allocation)  
  ٷ ʴ´.   C++   ϰ ϱ  C++ 
  ޸  ڵȭϴ  õѴ. ڹ   ޸
  ̼ ڵ óȴٴ ̴.  howto "C++" ޸
  鿡 ڹ () "/"ϴ  ϰ  ̴.

  C++ α׷ӵ  ޸ ̼Ƕ  ð ҺѴ.
    ִ  п ϴ ð   ִ 
   ̵   ̴.

  1.1.   C++ Ϸ  

  C++  C super-set   "C"     
  ִ.   , "C" α׷ֿ ޸  ޸
  ÷ο찡 ϴ.  ֳĸ   ʶ

  ______________________________________________________________________
          Datatype  char * and char[]
          String functions like strcpy, strcat, strncpy, strncat, etc..
          Memory functions like malloc, realloc, strdup, etc..
  ______________________________________________________________________

  char *  strcpy  "overflow" "fence past errors", ׸ "mem
  ory leaks"    ޸  ߱Ų.  ޸ 
  ϱ ſ ư, ġ trouble-shootϴµ  ð
  ҸŲ.  ޸  α׷ӵ 꼺 ҽŲ. 
   "C++" ޸  ؼ  ִ   ޵ 
   α׷ӵ 꼺   Ű° ´. ޸𸮿 õ
  ׵ ũϱ ſ ư  õ α׷ӵ鵵 ޸𸮿
  õ  ϴµ ,  Ȥ ޱ ɸ⵵ Ѵ.
   ޸ ׵   ڵȿ "" ̰
  װ͵ ġ ʾҴ α׷ 浹 ߱ų  ִ. char * 
    ̱ Ϻ  ϴ ð α׷  ų
  20 ظ ߱Ű ִ.  C++  char *  ϸ,
  Ư  α׷ 鸸 ̻ ڵ尡 ִٸ װ 
  غ ̴,

  ׷   "C"   غϱ   
  ϴ ̴.

  C++ Ϸ α׷ӵ "char *" , "char[]"  Ÿ԰
  strcpy, strcat, strncpy, strncat  Լ ϴ 
  ƾѴٰ Ѵ. char *, char[]   ŸԵ strcpy,
  strcat  Լ C++ 뿡 ־ ݵ  Ǿ߸
  ϴ طο ͵̴!!

   C++ α׷ӵ char * and char[]  ϴ ſ  
   'mychar class' STDLIB Ե 'string class'  ݵ
  ؾ Ѵ. 'mychar class'  ڿ Ҹڸ ̿ؼ ޸
   ڵȭϰ ltrim, substring  Լ Ѵ.

  C++ Ϸ ִ 'string class'   . string class 
  standard GNU C++ library  Ϻκ̰  stringԼ   Ѵ.
  string class'  'mychar class'   char * datatype  ʿ䰡
  .  , C++ α׷ӵ 'malloc' ̳ 'free'  
  'new' class'  Ϻϰ char datatype    ִ. 
  α׷ӵ ޸  ޸ ̼ǿ ؼ  
  ʿ䰡  󸶳 ̷ο ΰ.

  GNU C++ Ϸ char *, char[] datatypes   ݵ
  ؾϸ, char datatype ̿ α׷ ϱ   ؼ
  Ϸ "-fchar-datatype"  Ҹ ɼ g++ ɾ  ߰
   Ѵ.   2ȿ  C++ α׷ 'mychar class'
  and 'string class'   ɰ̰ char * and char[]   
  ̴. Ϸ  α׷    ϵ ؾѴ.

  1.2.  "C"  ΰ "C++"  ΰ ƴϸ ڹٸ ΰ?

   α׷̳ Ϲ  α׷ ؼ ü
   "C++" ̿ؼ α׷ ϴ° õȴ. "C++"
  ü     ִ.  -0̳ -03 
  Ϸ optimizerɼǵ C++ ӵ ų  ִ.

   "C"  ü, ̽ ̹ ϱ "ý
  α׷" ַ δ.

  ڹٴ   Ǵ GUI ϴµ  
  ÷   ſ  ȴ. C++ and HTML, DHTML
   Ҿ Fast-CGI ϴ°    ϱؼ C++
  and HTML, DHTML  Ҿ Fast-CGI ϴ° ٶϴ.

  2.  ٿε mychar

   α׷    ÷ο ִ.  Ѱ tar
  zipȭϷ ٿε   ִ.  mychar class, libraries, ׸ 
  α׷  ٿ  ִ.

  o  " http://www.aldev.8m.com " C++Programming howto.tar.gz
     file  ŬϽÿ.

  o  Mirror site :  <http://aldev.webjump.com>

  3.  mychar class 

  ִ.  'libmychar.a'   includeؾ ϰ  library  "C++"
  library ġ /usr/lib directory īؾѴ ('libmychar.a'
  ``Appendix H'' ִ makefile   ִ ). 'libmychar.a'
  ϱ  ؼ  α׷     Ͻÿ.

  ______________________________________________________________________
          g++ example.cpp -lmychar
  ______________________________________________________________________

   ڵ带 ÿ.

  ______________________________________________________________________
          mychar aa;

          aa = " Washington DC is the capital of USA ";

          // You can use aa.val like a 'char *' variable in programs !!
          for (unsigned long tmpii = 0; tmpii < aa.length(); tmpii++)
          {
                  fprintf(stdout, "aa.val[%ld]=%c ", tmpii, aa.val[tmpii]);
          }

          // Using pointers on 'char *' val ...
          // Note: You must use a temporary local variable and assign the
          // pointer to aa.val. If you directly use aa.val and when
          // aa.val is incremented with aa.val++, then aa will go
          // call destructor and later when aa.val is accessed that
          // will cause core dump !!
          for (char *tmpcc = aa.val; *tmpcc != 0; tmpcc++)
          {
                  // MUST use temporary variable tmpcc !! See note above.
                  fprintf(stdout, "aa.val=%c ", *tmpcc);
          }
  ______________________________________________________________________

  mychar class      α׷ "example_mychar.cpp" 
  ``Appendix A'' ְ mychar class  ``Appendix B'' ִ.

  3.1.  ڵ

  o  Equal to ==

  o  Not equal to !=

  o  Assignment =

  o  Add to itself and Assignment +=

  o  String concatenation or addition +

     ڵ  

     ___________________________________________________________________
             mychar aa;
             mychar bb("Bill Clinton");

             aa = "put some value string";  // assignment operator
             aa += "add some more"; // Add to itself and assign operator
             aa = "My name is" + " Alavoor Vasudevan "; // string cat operator

             if (bb == "Bill Clinton")  // boolean equal to operator
                     cout << "bb is eqaul to 'Bill Clinton' " << endl;

             if (bb != "Al Gore")   // boolean 'not equal' to operator
                     cout << "bb is not equal to 'Al Gore'" << endl;
     ___________________________________________________________________

  3.2.  Լ

  o   ڿ  length()

  o  ڿ  ߶󳻱. ó  -, -ϱ ltrim()

  o  ڿ  ߶󳻱. 󳪿 -, - ϱ rtrim()

  o  ó ߿   ϱ trim()

  o  󳪿  ϱ chop()

  o  ڿ 빮ڷ ٲٱ  to_upper()

  o  ڿ ҹڷ ٲٱ  to_lower()

  o  Ǽ ݿøϰų ϱ  roundf(float input_val, short
     precision)

  o  double ݿøϰų ϱ roundd(double input_val, short
     precision)

  o  startġ ڿ substr ġϴ ġ ãֱ pos(char
     *substr, unsigned long start)

  o  Explodes the string and returns the list in the list-head pointer
     explodeH explode(char *seperator)

  o  Implodes the strings in the list-head pointer explodeH and returns
     the mychar variable implode(char *glue)

  o  Ʈ   explodeH ڿ ̰ mychar ȯ
     join(char *glue)
  o  Է ڿ n ݺ repeat(char *input, unsigned int multiplier)

  o  ڿ ڸ reverse()

  o  ڿ needle ʴ val ã str ٲٱ
     replace(char *needle, char *str)

  o  Char  str_tr(char *from, char *to)

  o  ؽƮ ڿ ߾ӿ center(int length, char padchar =

  o   ڿ 鹮ڸ number padchar ٲپ ش.
      հ   ׻ ŵȴ.  number ų 0̸,
     ڿ    ŵȴ.number ⺻ 0̰
     padchar ⺻ . space(int number = 0, char padchar = '

  o  start end   ڵ ̷ ڿ ȯ
     xrange(char start, char end)

  o  list  ִ   . list ⺻ڴ 鹮
       compress(char *list)

  o  start ġ length ڸ ڿ . 
     statr ڿ ̺   ڿ  ʴ´.
     delstr(int start, int length)

  o  start  newstr val Ѵ. newstr
     length ڷ . ⺻ length newstr ڿ
      insert(char *newstr, int start = 0, int length = 0, char
     padchar =  ')

  o  Val  ʿ ִ length ڿ ȯ. ڿ 
     ٸ߱⿡   left(int length = 0, char padchar = ' ')

  o  Val  ʿ ִ length ڿ ȯ. ڿ
      ٸ߱⿡   right(int length = 0, char padchar = '

  o  newstr valȿ start   . newstr
     length ڷ . ⺻ length newstr 
     overlay(char *newstr, int start = 0, int length = 0, char padchar =
     ' ')

  o  ڿ κ . substr(int start, int length = 0)

  o  regx ó ġϴ  ã´. at(char *regx)

  o  Regx ڿ ȯ before(char *regx)

  o  Regxe ڿ ȯ after(char *regx)

  o  ڿ NULL̸  ȯ isnull()

  o  ڿ NULL clear()

  3.3.  Ÿ Լ

  Ÿ mychar Լ ⿡ Ƶξ.  ̰͵ 
  .   '+', '+=', '=='   ڵ ϶. ̰͵
  'mychar' class 'private'̴.

  o  Copy string str_cpy(char *bb)

  o  Long integer converted to string str_cpy(unsigned long bb)

  o  Integer converted to string str_cpy(int bb)

  o  Float converted to string str_cpy(float bb)

  o  String concatenate a char * str_cat(char *bb)

  o  String concatenate a int str_cat(int bb)

  o  String concatenate a int str_cat(unsigned long bb)

  o  String concatenate a float str_cat(float bb)

  o  Is equal to mychar ? bool equalto(const mychar & rhs, bool type =
     false)

  o  Is equal to char* ? bool equalto(const char *rhs, bool type =
     false)

        ڿ ٲٱ ؼ   ϶.

     ___________________________________________________________________
             mychar  aa;

             aa = 34;  // =  int  string  ٲ۴.
             cout << "The value of aa is : " << aa.val << endl;

             aa = 234.878; //  '='  float  string ٲ۴.
             cout << "The value of aa is : " << aa.val << endl;

             aa = 34 + 234.878;
             cout << "The value of aa is : " << aa.val << endl;
             // aa  '268.878'  ȴ.
             // mychar cast ؾ Ѵ.
             aa = (mychar) 34 + " Honourable President Ronald Reagan " + 234.878;
             cout << "The value of aa is : " << aa.val << endl;
             // '34 Honourable President Ronald Reagan 234.878'  µȴ.
     ___________________________________________________________________

  4.  C++ Zap (Delete) ɾ

  C++  delete  new ɾ "C" malloc  free Լ ξ .
  malloc  free ſ  new  zap (delete) ɾ   
  .  deleteɾ  Ȯ ϱ ؼ Zap() ɾ .
  zap() ɾ   ǵ  ִ.

  ______________________________________________________________________
  /*
  **Ϻϰ ưư ũθ   do while  Ѵ.
  ** ,  "do-while"  ,   
  **̴
  ** if (bbint == 4)
  **              aa = 0
  ** else
  **              zap(aptr); //߻! aptr ׻ NULL  ̴
  */

  #define zap(x) do { delete(x); x = NULL; } while (0)
  ______________________________________________________________________

     ͵  ͷ ȴٰ  Ѵٸ Ϸ
  zap() ɾ   new ͵ ϰ    ְ
   new   ͵    ִ.  ,

  ______________________________________________________________________
          zap(pFirstname);
          zap(pFirstname); // no core dumps !! Because pFirstname is NULL now
          zap(pFirstname); // no core dumps !! Because pFirstname is NULL now

          zap(pLastname);
          zap(pJobDescription);
  ______________________________________________________________________

  ̰  ű  ƴϴ. ̰  ݺǴ ڵ带 ̺ϰ
   б   ̴. zap() ɾ  typecast  
  -  zap() ɾ     װ 򰡿 ٸ
    ɼ ũ ̴.   ``my_malloc()'' , my_real
  loc() ׸ my_free()  ϰ additional checks ֱ⶧
  malloc(), realloc() and free(), ſ Ǿ Ѵ.  
  ``my_malloc()''  my_free() Լ  mychar.h" .  :
  'new'   ޸ free() Ǯų Ǵ malloc 
  ޸𸮸 'delete' Ǯ. ̷     .

  5.  my_malloc  my_free 

  malloc  realloc ϰ   new and zap(delete)  
  .   "C++" "C" Ÿ ޸ ̼ 
  ʿ䰡   ִ. Լ my_malloc() , my_realloc() and my_free()
  .  Լ allocations  initialisations  ϰ ޸
   Ѵ.   Լ (DEBUG 忡) Ʈ
  ޸𸮸 ϰ α׷ Ǳ   ޸ 
  ƮѴ. ̰ п ޸  ִ θ ˷ش.
  my_malloc  my_realloc  Ʒ  ǵȴ. ̰   
  ޸(SAFE_MEM = 5)  Ҵϰ  ʱȭѴ. ׸ ࿡
  α׷ȿ ̹ Ҵ Ǿ  Ҵ  ʴ´.
  'call_check(), remove_ptr()' Լ  DEBUG makefile 
  Ǿ ۵ ǰ  Լ  ((void)0) (  NULL for non-
  debug production release.)   assigned ȴ.  ׵  
  ޸𸮸 ϴ   Ѵ.

  ______________________________________________________________________
  void *local_my_malloc(size_t size, char fname[], int lineno)
  {
          size_t  tmpii = size + SAFE_MEM;
          void *aa = NULL;
          aa = (void *) malloc(tmpii);
          if (aa == NULL)
                  raise_error_exit(MALLOC, VOID_TYPE, fname, lineno);
          memset(aa, 0, tmpii);
          call_check(aa, tmpii, fname, lineno);
          return aa;
  }

  char *local_my_realloc(char *aa, size_t size, char fname[], int lineno)
  {
          remove_ptr(aa, fname, lineno);
          unsigned long tmpjj = 0;
          if (aa) // aa !=  NULL
                  tmpjj = strlen(aa);
          unsigned long tmpqq = size + SAFE_MEM;
          size_t  tmpii = sizeof (char) * (tmpqq);
          aa = (char *) realloc(aa, tmpii);
          if (aa == NULL)
                  raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno);

          // do not memset!! memset(aa, 0, tmpii);
          aa[tmpqq-1] = 0;
          unsigned long kk = tmpjj;
          if (tmpjj > tmpqq)
                  kk = tmpqq;
          for ( ; kk < tmpqq; kk++)
                  aa[kk] = 0;
          call_check(aa, tmpii, fname, lineno);
          return aa;
  }
  ______________________________________________________________________

  my_malloc α׷ full implementation  ؼ my_malloc.cpp. 
   ȭ my_malloc.h.  .  my_malloc  my_free 뿹 
  .

  ______________________________________________________________________
          char    *aa;
          int     *bb;
          float   *cc;
          aa = (char *) my_malloc(sizeof(char)* 214);
          bb = (int *) my_malloc(sizeof(int) * 10);
          cc = (float *) my_malloc(sizeof(int) * 20);

          aa = my_realloc(aa, sizeof(char) * 34);
          bb = my_realloc(bb, sizeof(int) * 14);
          cc = my_realloc(cc, sizeof(float) * 10);
  ______________________________________________________________________

  my_realloc   ü ޵ǰ, Ȯ my_realloc 
  ҷ⶧ (  Ÿ Ÿ Ͱ ȯǱ⶧)
  ŸŸ ȯ ʿ䰡 ٴ  ϶. my_realloc char*,
  int* ׸ float*  ߺ(overloaded) Լ  ִ.

  6.  Debug ȭϵ

  C++ ̳ C α׷ Ϸ debug.h ȭ includeŰ
  debug.h Լ Ű 'Makefile' ȿ DEBUG  ض.
  '-DDEBUG'  ϸ debug Լ calls ((void)0) i.e. NULL ȴ.
  ׷Ƿ Ʈ  production release  ƹ 
  ġ ʴ´.   α׷ debug Լ  
    production ȭ ũ⸦ Ű ʴ´.

  debug ƾ  ``debug.cpp'' ׸ debug.h  debug Լ
    ؼ ``my_malloc.cpp'' ȭ .  
  ``Makefile''  .

  7.  C++ Online 

   C++ Ʈ 湮 . :-

  o  C++ Crash-proof site
     <http://www.troubleshooters.com/codecorn/crashprf.htm>

  o  C++ Memory site
     <http://www.troubleshooters.com/codecorn/memleak.htm>

     ͳݿ  C++   ִ. Yahoo, Lycos, Infoseek,
     ׸ Excite   ġ  'C++ tutorials' 'C++
     references' 'C++ books'  Ű Ÿ ϸ ã  ִ.
     Advanced search  Ŭؼ ġ  з   ְ
     ֳ  Ȯ Ἥ ġ  ִ.

  o  <http://www.yahoo.com>

  o  <http://www.lycos.com>

  o  <http://www.infoseek.com>

  o  <http://www.excite.com>

  o  <http://www.mamma.com>

  7.1.  C++ Ʃ͸

  ͳݿ 밡   ¶ Ʃ͸ ִ. ġ 
  'C++ tutorials'  Ÿؼ ã  ִ.

  7.2.  C++ ڵ ǥ

    C++ ڵ URL  .

  o  C++ coding standard
     <http://www.cs.umd.edu/users/cml/cstyle/CppCodingStandard.html>

  o  Coding standards from Possibility
     <http://www.possibility.com/Cpp/CppCodingStandard.html>

  o  Coding standards from Ambysoft
     <http://www.ambysoft.com/javaCodingStandards.html>

  o  Rules and recommendations
     <http://www.cs.umd.edu/users/cml/cstyle/>

  o  Indent and annotate
     <http://www.cs.umd.edu/users/cml/cstyle/indhill-annot.html>

  o  Elemental rules  <http://www.cs.umd.edu/users/cml/cstyle/Ellemtel-
     rules.html>

  o  C++ style doc  <http://www.cs.umd.edu/users/cml/cstyle/Wildfire-
     C++Style.html>

  7.3.  C++  ۷

  ġ 'C++ Reference'  Ÿؼ ã  ִ.

  7.4.  C++  ׷

  o  C++ newsgroups :  <comp.lang.c++.announce>

  o  C++ newsgroups :  <comp.lang.c++.*>

  8.  ޸ 

   ޸     ִ.

  o   contrib cdrom ؼ mem_test*.rpm Ű  ȴ.

  o   õҿ ؼ ElectricFence*.rpm Ű  ȴ.

  o  Purify Tool from Rational Software Corp  <http://www.rational.com>

  o  Insure++ Tool from Parasoft Corp  <http://www.parasoft.com>

  o  Linux Tools at  <http://www.xnet.com/~blatura/linapp6.html#tools>

  o  Yahoo, Lycos, Excite, Ȥ Mamma.com   ͳ ġ
     "Linux memory debugging tools" Ű Ÿ ؼ ãƺ ȴ

  9.   URL

  C, C++  õ  ͳ Ʈ 湮 .

  o  Vim color text editor for C++, C
     <http://metalab.unc.edu/LDP/HOWTO/Vim-HOWTO.html>

  o  C++ Beautifier HOWTO  <http://metalab.unc.edu/LDP/HOWTO/C-
     C++Beautifier-HOWTO.html>

  o  CVS HOWTO for C++ programs  <http://metalab.unc.edu/LDP/HOWTO/CVS-
     HOWTO.html>

  o  Linux goodies main site  <http://www.aldev.8m.com>

  o  Linux goodies mirror site  <http://aldev.webjump.com>

  10.    ٸ 

    10 ٸ  -DVI, ƮũƮ, ؽ, LyX, GNU-
  info, HTML, RTF(Rich Text Format), Plain-text, Unix man pages ׸
  SGML -  Դ.

  o    HOWTO  HTML, DVI, Postscript Ȥ SGML   Ѱ
     tarȭϷ    ִ.
     <ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/other-formats/> or
     <ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/other-formats/>

  o  Plain text :  <ftp://metalab.unc.edu/pub/Linux/docs/HOWTO> or
     <ftp://metalab.unc.edu/pub/Linux/docs/HOWTO>

  o  Ҿ Ͼ, ξ, ߱ Ϻ  ܱ  
     <ftp://metalab.unc.edu/pub/Linux/docs/HOWTO> or
     <ftp://metalab.unc.edu/pub/Linux/docs/HOWTO>    ִ.
       ְ ϴ   ȯѴ.

     ̹ "SGML"  ̿ؼ ,  "SGML"  The document
     is written using a tool called "SGML tool" which can be got from -
     <http://www.xs4all.nl/~cg/sgmltools/>    ִ. ҽ
      ϸ   ɾ   ̴.

  o  sgml2html C++Programming-HOWTO.sgml     (to generate html file)

  o  sgml2rtf  C++Programming-HOWTO.sgml     (to generate RTF file)

  o  sgml2latex C++Programming-HOWTO.sgml    (to generate latex file)

     ִ.

  o  <http://metalab.unc.edu/LDP/HOWTO/C++Programming-HOWTO.html>

    ̷ Ʈ   ã  ִ.

  o  <http://www.caldera.com/LDP/HOWTO/C++Programming-HOWTO.html>

  o  <http://www.WGS.com/LDP/HOWTO/C++Programming-HOWTO.html>

  o  <http://www.cc.gatech.edu/linux/LDP/HOWTO/C++Programming-
     HOWTO.html>

  o  <http://www.redhat.com/linux-info/ldp/HOWTO/C++Programming-
     HOWTO.html>

  o  (Ʈũ ּҸ鿡)  ٸ ̷ Ʈ
     <http://metalab.unc.edu/LDP/hmirrors.html>  ã  ִ.
     Ʈ ϰ /LDP/HOWTO/C++Programming-HOWTO.html 丮
      ȴ.

    dvi  ؼ  xdvi α׷ ϸ ȴ.
  xdvi α׷    tetex-xdvi*.rpm Ű ȿ 
  |α׷(Applications) | Publishing | TeX ޴ư ؼ
  ã  ִ.

               dvi  б ؼ xdvi -geometry 80x90 howto.dvi 
               ɾ ־ Ѵ.
               ׸ 콺  ũ⸦ ϰ xdvi   
               ȴ.
               Ʒ ̱ ؼ ȭǥ Ű  ,  ٿ
               Ű ϰų
               'f', 'd', 'u', 'c', 'l', 'r', 'p', 'n'  Ű  øų
               Ʒ ߾ Ȥ   
                 ̵ϱ ؼ   ִ.
               expert ޴ ַ 'x'   ȴ.

  ȭ   ִ. ƮũƮ α׷ gv α׷ 
     ghostscript*.rpm Ű ְ gv α׷ gv*.rpm
  Ű ְ, ControlPanel | Applications | Graphics ޴ư
  ؼ ġ ãƳ  ִ. gv α׷ ƮũƮ
  ڰ ϵ  ִ. ƮũƮ gv OS/2 
  95 ׸ NT  ٸ ÷  ϴ.

  o  Get ghostscript for Windows 95, OS/2, and for all OSes from
     <http://www.cs.wisc.edu/~ghost>

           ƮũƮ  бؼ
            gv howto.ps  ɾ .
           ƮũƮ ϱ ؼ
            ghostscript howto.ps  .

  HTML   ݽ ׺ͳ ũμƮ ͳ
  ͽ÷ξ,  ٷ   Ȥ ٸ   Ἥ 
   ִ latex, LyX  LyX a "X-Windows" front end to latex 
  ̿   ִ.

  11.  ۱

  ۱  LDP (  Ʈ) μ GNU/GPL ̴. LDP 
  ϳ GNU/GPLƮ̴. ߰ 䱸Ǵ ͵μ  ̸,
  ̸ ּ, ׸  纻鿡  ۱ ׿  κ
  ־־ Ѵ.   ̶ ٲٰų    ߰ϰ Ǹ 
    ڵ鿡 װ ˷ֱ ٶ.

  12.  ÷ A example_mychar.cpp

   α׷ Download mychar   ϳ tar.gz ȭϷ
  ٿε   ִ.  ȭ   'Text'
  Ÿ  ϸ ȴ.

  ______________________________________________________________________
  //*****************************************************************
  //۱ GNU/GPL  ߰    ̸ ̸
  //Խ־ Ѵ.
  //: Al Dev  ̸: alavoor@yahoo.com
  //*****************************************************************
  //  Ϸ( libmychar.a  丮 ִٰ
  // ϰ )
  //              g++ example_mychar.cpp -L. -lmychar

  #include <stdlib.h>  // for putenv
  #include "mychar.h"

  /////////////////////////////////////////////////
  //mychar   α׷
  /////////////////////////////////////////////////

  int main(int argc, char **argv)
  {
          char p_name[1024];
          sprintf(p_name, "PROGRAM_NAME=%s", argv[0]);
          putenv(p_name);
          print_total_memsize(); // in the beginning
          mychar aa, bb;

          //bb.str_cpy("  bbSTRing  ");
          bb = "   bbSTRing   ";

          //+  ׽Ʈϱ
          //aa + " rhs "; //  ⼭  µ  ʰ ɰ̴ !!
          //ݵ ٿ   ó  fprintf  ؾ Ѵ.
          fprintf(stdout, "\n0) aa.val is :%sEOF\n", (aa + " my rhs " ).val);

          //= ׽Ʈϱ
          aa = " lhs " ;
          fprintf(stdout, "0-1) With operator= aa.val is :%sEOF\n", aa.val);

          //+  ׽Ʈ ϱ
          //aa + " rhs "; //  ⼭  µ  ʰ ɰ̴ !!
          //ݵ ٿ   ó  fprintf  ؾ Ѵ.
          fprintf(stdout, "\n0) With lsh operator+, aa.val is :%sEOF\n", (" my lhs " + aa ).val);

          //aa.str_cpy(bb.val);
          aa = bb;
          aa.to_upper();
          fprintf(stdout, "1) aa.val is :%sEOF\n", aa.val);

          aa = bb;
          aa.to_lower();
          fprintf(stdout, "2) aa.val is :%sEOF\n", aa.val);

          aa = bb;
          aa.ltrim();
          fprintf(stdout, "3) aa.val is :%sEOF\n", aa.val);

          aa = bb;
          aa.rtrim();
          fprintf(stdout, "4) aa.val is :%sEOF\n", aa.val);

          aa = bb;
          aa.trim();
          fprintf(stdout, "5) aa.val is :%sEOF\n", aa.val);

          aa = bb;
          aa = aa + " testing newlines \n\n\n\n";
          aa.chop();
          fprintf(stdout, "5-1) aa.val is :%sEOF\n", aa.val);

          aa = bb;
          aa = aa + " rhs ";
          fprintf(stdout, "6) aa.val is :%sEOF\n", aa.val);

          aa = bb;
          aa = " lhs " + aa;
          fprintf(stdout, "7) aa.val is :%sEOF\n", aa.val);

          //  ϱ 
          //aa = (mychar) 9989 + "kkk" + 33 ;
          aa = 9999;
          fprintf(stdout, "7-1) aa.val is :%sEOF\n", aa.val);

          aa = bb;
          aa = " lhs " + aa + " rhs " + " 9989 " + " 33 ";
          fprintf(stdout, "8) aa.val is :%sEOF\n", aa.val);

          aa = " AA value ";
          aa = bb + "alkja " + " 99djd " ;
          fprintf(stdout, "9) aa.val is :%sEOF\n", aa.val);

          aa = " AA value ";
          aa = (mychar) "alkja " + " 99djd " ;
          fprintf(stdout, "10) aa.val is :%sEOF\n", aa.val);

          aa = " AA value ";
          aa += (mychar) " al dev test kkk... " + " al2 slkj" + " al3333 ";
          fprintf(stdout, "11) aa.val is :%sEOF\n", aa.val);

          aa = " AA value ";
          aa = aa + " add aa " + aa + aa + aa + " 1111 " + " 2222 " + aa + aa + aa + " 3333 ";
          fprintf(stdout, "12) aa.val is :%sEOF\n", aa.val);

          aa = "12345678";
          aa.reverse();
          fprintf(stdout, "13) aa.val is :%sEOF\n", aa.val);

          aa = " AA value ";
          aa = aa + " add aa " + aa + 1111 +" "+ 2222 + " " + 3.344 + aa;
          fprintf(stdout, "14) aa.val is :%sEOF\n", aa.val);

          aa.roundd(123456.0123456789012345, 13);
          fprintf(stdout, "15) double aa.val is :%sEOF\n", aa.val);

          aa.roundf(123456.0123456789, 13);
          fprintf(stdout, "16) float aa.val is :%sEOF\n", aa.val);

          // Test equal to operators
          aa = " AA value ";
          mychar cc(" AA value ");
          if (aa == cc)
                  fprintf(stdout, "\naa=%s and cc=%s are equal!!\n", aa.val, cc.val);
          else
                  fprintf(stdout, "\naa=%s and cc=%s are NOT equal!!\n", aa.val, cc.val);
          cc = "CC";
          if (aa == cc)
                  fprintf(stdout, "\naa=%s and cc=%s are equal!!\n", aa.val, cc.val);
          else
                  fprintf(stdout, "\naa=%s and cc=%s are NOT equal!!\n", aa.val, cc.val);
          if (aa == " AA value ")
                  fprintf(stdout, "\naa=%s and string are equal!!\n", aa.val);
          else
                  fprintf(stdout, "\naa=%s and string are NOT equal!!\n", aa.val);
          if (aa == " AA valuexxx ")
                  fprintf(stdout, "\naa=%s and string are equal!!\n", aa.val);
          else
                  fprintf(stdout, "\naa=%s and string are NOT equal!!\n", aa.val);

          //aa.val  'char *' ó α׷   ִ!!
          fprintf(stdout, "\n ");
          for (unsigned long tmpii = 0; tmpii < aa.length(); tmpii++)
          {
                  fprintf(stdout, "aa.val[%ld]=%c ", tmpii, aa.val[tmpii]);
          }
          fprintf(stdout, "\n");

          //'char *' val ...  ϱ
          fprintf(stdout, "\n ");

          for (char *tmpcc = aa.val; *tmpcc != 0; tmpcc++)
          {
                  // MUST use temporary var tmpcc !! See note above.
                  fprintf(stdout, "aa.val=%c ", *tmpcc);
          }
          fprintf(stdout, "\n");

          print_total_memsize(); // in the end
          exit(0);
  }
  ______________________________________________________________________

  13.  ÷ B mychar.h

  Download mychar   α׷ ϳ tar.gz ȭϷ
  ٿε  ִ.  ȭ    ȭ
  'Text' Ÿ Ѵ.

  ______________________________________________________________________
  //*****************************************************************
  //۱ GNU/GPL    ̸ ̸  纻
  //ԽѾ Ѵ.
  //: Al Dev  ̸: alavoor@yahoo.com
  //*****************************************************************

  //޸ ϱؼ - a char class to manage character
  //variables
  //char[] Ȥ char *  mychar  string class  ϴ  .

  #ifndef __MYCHAR_H_
  #define __MYCHAR_H_

  //#include <iostream> // iostream α׷ Ŀϱ  ʴ´.
  //#include <stdlib.h> //free() malloc()  
  #include <string.h> // for strcpy()
  #include <ctype.h> // for isspace()
  #include <stdio.h> // for sprintf()
  #include <list.h> // for sprintf()
  #include <math.h> // for modf(), rint()

  #include "my_malloc.h"
  #include "debug.h" // debug_(name, value)  debug2_(name, value, LOG_YES)

  const short INITIAL_SIZE =      50;
  const short NUMBER_LENGTH = 70;

  // ּ Լ    Ŭ (class)
  // This class to be kept small...  Ŭ  ۰ ɰ̴.
  class mychar
  {
          public:
                  mychar();
                  mychar(char bb[]);  // needed by operator+
                  mychar(int bb);  // needed by operator+
                  mychar(unsigned long bb);  // needed by operator+
                  mychar(float bb);  // needed by operator+
                  mychar(double bb);  // needed by operator+
                  mychar(const mychar & rhs);  // Copy Constructor needed by operator+
                  ~mychar();

                  char *val;

                  unsigned long length() { return strlen(val); }

                  void ltrim();
                  void rtrim();
                  void trim();
                  void chop();

                  void to_upper();
                  void to_lower();

                  void roundf(float input_val, short precision);
                  void decompose_float(long *integral, long *fraction);

                  void roundd(double input_val, short precision);
                  void decompose_double(long *integral, long *fraction);

                  long pos(char substr[], unsigned long start);

                  void explode(char *seperator);
                  void implode(char *glue);
                  void join(char *glue);
                  void repeat(char *input, unsigned int multiplier);
                  void reverse();
                  void replace(char *needle, char *str);
                  void str_tr(char *from, char *to);
                  void center(int length, char padchar = ' ');
                  void space(int number = 0, char padchar = ' ');
                  void xrange(char start, char end);
                  void compress(char *list);
                  void delstr(int start, int length);
                  void insert(char *newstr, int start = 0, int length = 0, char padchar = ' ');
                  void left(int length = 0, char padchar = ' ');
                  void right(int length = 0, char padchar = ' ');
                  void overlay(char *newstr, int start = 0, int length = 0, char padchar = ' ');
                  mychar substr(int start, int length = 0);

                  mychar at(char *regx); // matches first match of regx
                  mychar before(char *regx); // returns string before regx
                  mychar after(char *regx); // returns string after regx

                  bool isnull();
                  void clear();

                  // All Operators ...
                  mychar operator+ (const mychar & rhs);
                  friend mychar operator+ (const mychar & lhs, const mychar & rhs);

                  mychar& operator+= (const mychar & rhs); // using reference will be faster
                  mychar& operator= (const mychar & rhs); // using reference will be faster
                  bool operator== (const mychar & rhs); // using reference will be faster
                  bool operator== (const char *rhs);
                  bool operator!= (const mychar & rhs);
                  bool operator!= (const char *rhs);

                  static  list<mychar>            explodeH;  // list head

          private:
                  //static mychar *global_mychar; // for use in add operator
                  //inline void free_glob(mychar **aa);
                  void str_cpy(char bb[]);
                  void str_cpy(int bb); // itoa
                  void str_cpy(unsigned long bb);
                  void str_cpy(float bb); // itof

                  void str_cat(char bb[]);
                  void str_cat(int bb);
                  void str_cat(unsigned long bb);
                  void str_cat(float bb);

                  bool equalto(const mychar & rhs, bool type = false);
                  bool equalto(const char *rhs, bool type = false);
  };
  // Global variables are defined in mychar.cpp

  #endif // __MYCHAR_H_
  ______________________________________________________________________

  14.  ÷ C mychar.cpp

  Download mychar   α׷ ϳ tar.gz ȭϷ
  ٿε  ִ.  ȭ    ȭ
  Text' Ÿ Ѵ.

  ______________________________________________________________________
  //*****************************************************************
  //۱ GNU/GPL    ̸ ̸  纻
  //ԽѾ Ѵ.
  //: Al Dev  ̸: alavoor@yahoo.com
  //*****************************************************************

  //ڿ Ŭ  Ŭ Ѵ.
  //
  //޸ ϱؼ - a char class to manage character
  //variables
  //char[] Ȥ char *  mychar  string class  ϴ  .

  //     
  //              g++ mychar.cpp

  #include "mychar.h"

  // Global variables ....
  //mychar *mychar::global_mychar = NULL; // global var
  list<mychar>            mychar::explodeH;

  mychar::mychar()
  {
          debug_("In cstr()", "ok");
          val = (char *) my_malloc(sizeof(char)* INITIAL_SIZE);
  }

  mychar::mychar(char *bb)
  {
          unsigned long tmpii = strlen(bb);
          val = (char *) my_malloc(sizeof(char)* tmpii);
          strncpy(val, bb, tmpii);
          val[tmpii] = '\0';

          //debug_("In cstr(char *bb) bb", bb);
          //debug_("In cstr(char *bb) val", val);
          #ifdef DEBUG
                  //fprintf(stderr, "\nAddress of val=%x\n", & val);
                  //fprintf(stderr, "\nAddress of this-pointer=%x\n", this);
          #endif // DEBUG
  }

  mychar::mychar(int bb)
  {
          val = (char *) my_malloc(NUMBER_LENGTH); // integers 70 digits max
          sprintf(val, "%d", bb);
  }

  mychar::mychar(unsigned long bb)
  {
          val = (char *) my_malloc(NUMBER_LENGTH); // long 70 digits max
          sprintf(val, "%lu", bb);
  }

  mychar::mychar(float bb)
  {
          val = (char *) my_malloc(NUMBER_LENGTH); // float 70 digits max
          sprintf(val, "%f", bb);
  }

  mychar::mychar(double bb)
  {
          val = (char *) my_malloc(NUMBER_LENGTH); // double 70 digits max
          sprintf(val, "%f", bb);
  }
  // Copy Constructor needed by operator +
  mychar::mychar(const mychar & rhs)
  {
          // Do a deep-copy instead of compiler's default shallow copy copy-cstr
          debug_("In copy-cstr()", "ok");
          unsigned long tmpii = strlen(rhs.val);
          val = (char *) my_malloc(sizeof(char)* tmpii);
          strncpy(val, rhs.val, tmpii);
          val[tmpii] = '\0';
  }

  mychar::~mychar()
  {
          //debug_("In dstr val", val);
          #ifdef DEBUG
                  //fprintf(stderr, "\nAddress of val=%x\n", & val);
                  //fprintf(stderr, "\nAddress of this-pointer=%x\n", this);
          #endif // DEBUG
          my_free(val);
          //delete [] val;
          val = NULL;
  }

  // MUST use pointer-to-pointer **aa, otherwise the argument
  // is NOT freed !!
  /*
  inline void mychar::free_glob(mychar **aa)
  {
          debug_("called free_glob()", "ok" );
          if (*aa != NULL)  // (*aa != NULL)
          {
                  debug_("*aa is not null", "ok");
                  delete *aa;
                  *aa = NULL;
          }
          //else
                  debug_("*aa is null", "ok");

          //if (*aa == NULL)
          debug_("*aa set to null", "ok");
  }
  */

  // Explodes the string and returns the list in
  // the list-head pointer explodeH
  void mychar::explode(char *seperator)
  {
          char *aa = NULL, *bb = NULL;
          aa = (char *) my_malloc(length());
          for (bb = strtok(aa, seperator); bb != NULL; bb = strtok(NULL, seperator) )
          {
                  mychar *tmp = new mychar(bb);
                  mychar::explodeH.insert(mychar::explodeH.end(), *tmp);
          }
          my_free(aa);

          list<mychar>::iterator iter1; // see file include/g++/stl_list.h
          debug_("Before checking explode..", "ok");
          if (mychar::explodeH.empty() == true )
          {
                  debug_("List is empty!!", "ok");
          }

          for (iter1 = mychar::explodeH.begin(); iter1 != mychar::explodeH.end(); iter1++)
          {
                  if (iter1 == NULL)
                  {
                          debug_("Iterator iter1 is NULL!!", "ok" );
                          break;
                  }
                  debug_("(*iter1).val", (*iter1).val);
          }
  }

  // Implodes the strings in the list-head
  // pointer explodeH and returns the mychar class
  void mychar::implode(char *glue)
  {
  }

  // Joins the strings in the list-head
  // pointer explodeH and returns the mychar class
  void mychar::join(char *glue)
  {
          implode(glue);
  }

  // Repeat the input string n times
  void mychar::repeat(char *input, unsigned int multiplier)
  {
          // For example -
          // repeat("1", 4) returns "1111"
          if (!input) // input == NULL
          {
                  val[0] = 0;
                  return;
          }

          val = (char *) my_malloc(strlen(input) * multiplier);
          for (unsigned int tmpii = 0; tmpii < multiplier; tmpii++)
          {
                  strcat(val, input);
          }
  }

  // Reverse the string
  void mychar::reverse()
  {
          // For example -
          //              reverse() on "12345" returns "54321"
          char aa;
          unsigned long tot_len = length();
          unsigned long midpoint = tot_len / 2;
          for (unsigned long tmpjj = 0; tmpjj < midpoint; tmpjj++)
          {
                  aa = val[tmpjj];  // temporary storage var
                  val[tmpjj] = val[tot_len - tmpjj - 1];  // swap the values
                  val[tot_len - tmpjj - 1] = aa; // swap the values
          }
  }

  // Replace all occurences of string 'needle' with 'str' in the haystack 'val'
  void mychar::replace(char *needle, char *str)
  {
          // For example -
          //              replace("AAA", "BB") on val = "some AAA and AAACC"
          //              reurns val = "some BB and BBCC"
  }

  // Translate certain chars
  void mychar::str_tr(char *from, char *to)
  {
          // For e.g ("abcd", "ABC") translates all occurences of each
          // character in 'from' to corresponding character in 'to'
  }

  // Center the text
  void center(int length, char padchar = ' ')
  {
          // For example -
          //              center(10, '*') on val="aa" returns "****aa****"
          //              center(10) on val="aa" returns "    aa    "
          // The result is a string of 'length' characters with val centered in it.
  }

  // Formats the original string by placing <number> of <padchar> characters
  // between each set of blank-delimited words. Leading and Trailing blanks
  // are always removed. If <number> is omitted or is 0, then all spaces are
  // in the string are removed. The default number is 0 and
  // default padchar ' '
  void space(int number, char padchar = ' ')
  {
          // For example -
          //              space(3) on val = "I do not know"
          //                              will return "I   do   not   know"
          //              space(1, '_') on val = "A deep black space"
          //                              will return "A_deep_black_space"
          //              space() on val = "I   know     this"
          //                              will return "Iknowthis"
  }

  // The result is string comprised of all characters between
  // and including <start> and <end>
  void xrange(char start, char end)
  {
          // For example -
          //      xrange('a', 'j') returns val = "abcdefghij"
          //      xrange(1, 8) returns val = "12345678"
  }

  // Removes any characters contained in <list>. The default character
  // for <list> is a blank ' '
  void compress(char *list)
  {
          // For example -
          //      compress("$,%") on val = "$1,934" returns "1934"
          //      compress() on val = "call me alavoor vasudevan" returns "callmealavoorvasudevan"
  }

  // Deletes a portion of string of <length> characters from <start> position.
  // If start is greater than the string length then string is unchanged.
  void delstr(int start, int length)
  {
          // For example -
          //      delstr(3,3) on val = 'pokemon' returns 'poon'
  }

  // The <newstr> in inserted into val beginning at <start>. The <newstr> will
  // be padded or truncated to <length> characters. The default <length> is
  // string length of newstr
  void insert(char *newstr, int start = 0, int length = 0, char padchar = ' ')
  {
          // For example -
          //      insert("something new", 4, 20, '*') on val = "old thing"
          //              returns "old something new*******thing"
  }

  // The result is string of <length> chars madeup of leftmost chars in val.
  // Quick way to left justify a string.
  void left(int length = 0, char padchar = ' ')
  {
          // For example -
          //      left(10) on val = "Wig" returns "Wig      "
          //      left(4) on val = "Wighat" returns "Wigh"
  }

  // The result is string of <length> chars madeup of rightmost chars in val.
  // Quick way to right justify a string.
  void right(int length = 0, char padchar = ' ')
  {
          // For example -
          //      right(10) on val = "never stop to saying" returns " to saying"
          //      right(4) on val = "Wighat" returns "ghat"
          //      right(6) on val = "4.50" returns "  4.50"
  }

  // The <newstr> in overlayed into val beginning at <start>. The <newstr> will
  // be padded or truncated to <length> characters. The default <length> is
  // string length of newstr
  void overlay(char *newstr, int start = 0, int length = 0, char padchar = ' ')
  {
          // For example -
          //      overlay("12345678", 4, 10, '*') on val = "oldthing is very bad"
          //              returns "old12345678**ery bad"
  }

  // sub string
  mychar mychar::substr(int start, int length = 0)
  {
          if (!length) // length == 0
                  return(mychar(& val[start-1]) );
          else
          {
                  mychar tmp = mychar(& val[start-1]);
                  tmp.val[length-1] = 0;
                  return(tmp);
          }
  }

  // If string is literrally equal to .. or not equal to
  // If type is false then it is ==
  bool mychar::equalto(const mychar & rhs, bool type = false)
  {
          if (type == false) // test for ==
          {
                  if (strlen(rhs.val) == length())
                  {
                          if (!strncmp(rhs.val, val, length())) //  == 0
                                  return true;
                          else
                                  return false;
                  }
                  else
                          return false;
          }
          else // test for !=
          {
                  if (strlen(rhs.val) != length())
                  {
                          if (!strncmp(rhs.val, val, length())) //  == 0
                                  return true;
                          else
                                  return false;
                  }
                  else
                          return false;
          }
  }

  // If string is literrally equal to .. or not equal to
  // If type is false then it is ==
  bool mychar::equalto(const char *rhs, bool type = false)
  {
          if (type == false) // test for ==
          {
                  if (strlen(rhs) == length())
                  {
                          if (!strncmp(rhs, val, length())) //  == 0
                                  return true;
                          else
                                  return false;
                  }
                  else
                          return false;
          }
          else // test for !=
          {
                  if (strlen(rhs) != length())
                  {
                          if (!strncmp(rhs, val, length())) //  == 0
                                  return true;
                          else
                                  return false;
                  }
                  else
                          return false;
          }
  }

  // find position, matching substr beginning from start..
  long mychar::pos(char *substr, unsigned long start)
  {
          char * tok;
          long res = -1;

          if ( !isnull() && (start < strlen(val) ) )
          {
                  tok = strstr(val + start, substr);
                  if (tok == NULL)
                          res = -1;
                  else
                          res = (long) (tok - val);
          }
          return res;
  }

  bool mychar::isnull()
  {
          if (val[0] == '\0')
                  return true;
          else
          {
                  if (val == NULL)
                          return true;
                  else
                          return false;
          }
  }

  void mychar::clear()
  {
          val = (char *) my_realloc(val, 10);
          val[0] = '\0';
  }

  // Remove trailing new-lines
  void mychar::chop()
  {
          unsigned long tmpii = strlen(val) - 1 ;
          for (; tmpii >= 0; tmpii--)
          {
                  if (val[tmpii] == '\n')
                          val[tmpii] = 0;
                  else
                          break;
          }
  }

  void mychar::ltrim()
  {
          // May cause problems in my_realloc since
          // location of bb will be destroyed !!
          char *bb = val;

          if (bb == NULL)
                  return;

          while (isspace(*bb))
                  bb++;
          debug_("bb", bb);

          if (bb != NULL && bb != val)
          {
                  debug_("doing string copy", "done");
                  //str_cpy(bb); // causes problems in my_realloc and bb is getting destroyed!!
                  strcpy(val, bb); // strcpy is ok since val space is > bb space
          }
          else
                  debug_("Not doing string copy", "done");
  }

  void mychar::rtrim()
  {
          for (long tmpii = strlen(val) - 1 ; tmpii >= 0; tmpii--)
          {
                  if ( isspace(val[tmpii]) )
                          val[tmpii] = '\0';
                  else
                          break;
          }
  }

  void mychar::trim()
  {
          rtrim();
          ltrim();
  }

  void mychar::to_lower()
  {
          for (long tmpii = strlen(val); tmpii >= 0; tmpii--)
          {
                  val[tmpii] = tolower(val[tmpii]);
          }
  }

  // Use for rounding off fractions digits of floats
  // Rounds-off floats with given precision and then
  // stores the result into mychar's val field
  // Also returns the result as a char *
  void mychar::roundf(float input_val, short precision)
  {
          float   integ_flt, deci_flt;
          const   short MAX_PREC = 4;

          debug_("In roundf", "ok");

          if (precision > MAX_PREC) // this is the max reliable precision
                  precision = MAX_PREC;

          // get the integral and decimal parts of the float value..
          deci_flt = modff(input_val, & integ_flt);

          for (int tmpzz = 0; tmpzz < precision; tmpzz++)
          {
                  debug_("deci_flt", deci_flt);
                  deci_flt *= 10;
          }
          debug_("deci_flt", deci_flt);

          unsigned long deci_int = (unsigned long) ( rint(deci_flt) );

          val = (char *) my_malloc(NUMBER_LENGTH); // float 70 digits max

          if (deci_int > 999) // (MAX_PREC) digits
                  sprintf(val, "%lu.%lu", (unsigned long) integ_flt, deci_int);
          else
          if (deci_int > 99) // (MAX_PREC - 1) digits
                  sprintf(val, "%lu.0%lu", (unsigned long) integ_flt, deci_int);
          else
          if (deci_int > 9) // (MAX_PREC - 2) digits
                  sprintf(val, "%lu.00%lu", (unsigned long) integ_flt, deci_int);
          else
                  sprintf(val, "%lu.00000%lu", (unsigned long) integ_flt, deci_int);
  }

  void mychar::roundd(double input_val, short precision)
  {
          double  integ_flt, deci_flt;
          const   short MAX_PREC = 6;

          if (precision > MAX_PREC) // this is the max reliable precision
                  precision = MAX_PREC;

          debug_("In roundd", "ok");
          // get the integral and decimal parts of the double value..
          deci_flt = modf(input_val, & integ_flt);

          for (int tmpzz = 0; tmpzz < precision; tmpzz++)
          {
                  debug_("deci_flt", deci_flt);
                  deci_flt *= 10;
          }
          debug_("deci_flt", deci_flt);

          val = (char *) my_malloc(NUMBER_LENGTH); // double 70 digits max

          unsigned long deci_int = (unsigned long) ( rint(deci_flt) );

          if (deci_int > 99999) // (MAX_PREC) digits
                  sprintf(val, "%lu.%lu", (unsigned long) integ_flt, deci_int);
          else
          if (deci_int > 9999) // (MAX_PREC - 1) digits
                  sprintf(val, "%lu.0%lu", (unsigned long) integ_flt, deci_int);
          else
          if (deci_int > 999) // (MAX_PREC - 2) digits
                  sprintf(val, "%lu.00%lu", (unsigned long) integ_flt, deci_int);
          else
          if (deci_int > 99) // (MAX_PREC - 3) digits
                  sprintf(val, "%lu.000%lu", (unsigned long) integ_flt, deci_int);
          else
          if (deci_int > 9) // (MAX_PREC - 4) digits
                  sprintf(val, "%lu.0000%lu", (unsigned long) integ_flt, deci_int);
          else // (MAX_PREC - 5) digits
                  sprintf(val, "%lu.00000%lu", (unsigned long) integ_flt, deci_int);
  }

  void mychar::to_upper()
  {
          for (long tmpii = strlen(val); tmpii >= 0; tmpii--)
          {
                  val[tmpii] = toupper(val[tmpii]);
          }
  }

  void mychar::str_cpy(char bb[])
  {
          debug_("In str_cpy bb", bb);
          if (bb == NULL)
          {
                  val[0] = '\0';
                  return;
          }

          unsigned long tmpii = strlen(bb);

          if (tmpii == 0)
          {
                  val[0] = '\0';
                  return;
          }

          debug_("In str_cpy tmpii", tmpii);
          debug_("In str_cpy val", val);
          val = (char *) my_realloc(val, tmpii);
          //val = new char [tmpii + SAFE_MEM_2];
          debug_("In str_cpy bb", bb);

          strncpy(val, bb, tmpii);
          debug_("In str_cpy val", val);
          val[tmpii] = '\0';
          debug_("In str_cpy val", val);
  }

  void mychar::str_cpy(int bb)
  {
          char tmpaa[100];
          sprintf(tmpaa, "%d", bb);
          str_cpy(tmpaa);
  }

  void mychar::str_cpy(unsigned long bb)
  {
          char tmpaa[100];
          sprintf(tmpaa, "%ld", bb);
          str_cpy(tmpaa);
  }

  void mychar::str_cpy(float bb)
  {
          char tmpaa[100];
          sprintf(tmpaa, "%f", bb);
          str_cpy(tmpaa);
  }

  void mychar::str_cat(char bb[])
  {
          unsigned long tmpjj = strlen(bb), tmpii = strlen(val);
          val = (char *) my_realloc(val, tmpii + tmpjj);
          debug_("val in str_cat() ", val);
          strncat(val, bb, tmpjj);
  }

  void mychar::str_cat(int bb)
  {
          char tmpaa[100];
          sprintf(tmpaa, "%d", bb);

          unsigned long tmpjj = strlen(tmpaa), tmpii = strlen(val);
          val = (char *) my_realloc(val, tmpii + tmpjj);
          strncat(val, tmpaa, tmpjj);
  }

  void mychar::str_cat(unsigned long bb)
  {
          char tmpaa[100];
          sprintf(tmpaa, "%ld", bb);

          unsigned long tmpjj = strlen(tmpaa), tmpii = strlen(val);
          val = (char *) my_realloc(val, tmpii + tmpjj);
          strncat(val, tmpaa, tmpjj);
  }

  void mychar::str_cat(float bb)
  {
          char tmpaa[100];
          sprintf(tmpaa, "%f", bb);

          unsigned long tmpjj = strlen(tmpaa), tmpii = strlen(val);
          val = (char *) my_realloc(val, tmpii + tmpjj);
          strncat(val, tmpaa, tmpjj);
  }

  mychar operator+ (const mychar & lhs, const mychar & rhs)
  {
          /*******************************************************/
          // Note : For adding two char strings, first cast mychar
          // as in -
          //aa = (mychar) "alkja " + " 99djd " ;
          /*******************************************************/

          mychar tmp(lhs);
          tmp.str_cat(rhs.val);
          return(tmp);

          /*
          if (mychar::global_mychar == NULL)
          {
                  mychar::global_mychar = new mychar;
                  mychar::global_mychar->str_cpy(lhs.val);
                  mychar::global_mychar->str_cat(rhs.val);
                  //return *mychar::global_mychar;
                  return mychar(mychar::global_mychar->val);
          }
          */
          /*
          else
          if (mychar::global_mychar1 == NULL)
          {
                  debug_("1)global", "ok" );
                  mychar::global_mychar1 = new mychar;
                  mychar::global_mychar1->str_cpy(lhs.val);
                  mychar::global_mychar1->str_cat(rhs.val);
                  return *mychar::global_mychar1;
          }
          */
          /*
          else
          {
                  fprintf(stderr, "\nError: cannot alloc global_mychar\n");
                  exit(-1);
          }
          */

          /*
          mychar *aa = new mychar;
          aa->str_cpy(lhs.val);
          aa->str_cat(rhs.val);
          return *aa;
          */
  }

  mychar mychar::operator+ (const mychar & rhs)
  {
          mychar tmp(*this);
          tmp.str_cat(rhs.val);
          debug_("rhs.val in operator+", rhs.val );
          debug_("tmp.val in operator+", tmp.val );
          return (tmp);
  }

  // Using reference will be faster in = operator
  mychar& mychar:: operator= ( const mychar& rhs )
  {
          if (& rhs == this)
          {
                  debug_("Fatal Error: In operator(=). rhs is == to 'this pointer'!!", "ok" );
                  return *this;
          }

          this->str_cpy(rhs.val);
          debug_("rhs value", rhs.val );

          // Free global vars memory
          //free_glob(& mychar::global_mychar);
          //if (mychar::global_mychar == NULL)
                  //fprintf(stderr, "\nglobal_mychar is freed!\n");

          //return (mychar(*this));
          return *this;
  }

  // Using reference will be faster in = operator
  mychar& mychar::operator+= (const mychar & rhs)
  {
          /*******************************************************/
          // Note : For adding two char strings, first cast mychar
          // as in -
          //aa += (mychar) "cccc" + "dddd";
          /*******************************************************/
          if (& rhs == this)
          {
                  debug_("Fatal error: In operator+= rhs is equals 'this' ptr", "ok");
                  return *this;
          }
          this->str_cat(rhs.val);
          return *this;
          //return (mychar(*this));
  }

  bool mychar::operator== (const mychar & rhs)
  {
          return(equalto(rhs.val));
  }

  bool mychar::operator== (const char *rhs)
  {
          return(equalto(rhs));
  }

  bool mychar::operator!= (const mychar & rhs)
  {
          return(equalto(rhs.val, true));
  }

  bool mychar::operator!= (const char *rhs)
  {
          return(equalto(rhs, true));
  }
  ______________________________________________________________________

  15.  ÷ D my_malloc.cpp

  Download mychar   α׷ ϳ tar.gz ȭϷ
  ٿε  ִ.  ȭ    ȭ
  'Text' Ÿ Ѵ.

  ______________________________________________________________________
  //*****************************************************************
  //۱ GNU/GPL    ̸ ̸  纻
  //ԽѾ Ѵ.
  //: Al Dev  ̸: alavoor@yahoo.com
  //*****************************************************************

  /*
  **      In your main() function put these lines -
                  char p_name[1024];
                  sprintf(p_name, "PROGRAM_NAME=%s", argv[0]);
                  putenv(p_name);
                  print_total_memsize(); // in the beginning
                  ......
                  ......
                  print_total_memsize(); // in the end
  */

  #include <stdio.h>
  #include <alloc.h>  // for c++ -- malloc, alloc etc...
  #include <stdlib.h>  // malloc, alloc..
  #include <time.h>  // strftime, localtime, ...
  #include <list.h>  // strftime, localtime, ...  see file include/g++/stl_list.h
  //#include <debug.h> // debug_("a", a);  debug2_("a", a, true);

  #include "my_malloc.h"

  const short SAFE_MEM = 10;
  const short DATE_MAX_SIZE = 200;

  const short MALLOC = 1;
  const short REALLOC     = 2;

  const short VOID_TYPE =         1;
  const short CHAR_TYPE =         2;
  const short SHORT_TYPE =        3;
  const short INT_TYPE =          4;
  const short LONG_TYPE =         5;
  const short FLOAT_TYPE =        6;
  const short DOUBLE_TYPE =       7;

  const char LOG_FILE[30] = "memory_error.log";

  // Uncomment this line to debug total mem size allocated...
  //#define DEBUG_MEM  "debug_memory_sizes_allocated"

  static void raise_error_exit(short mtype, short datatype, char fname[], int lineno);

  #ifdef DEBUG
  class MemCheck
  {
          public:
                  MemCheck(void *aptr, size_t amem_size, char fname[], int lineno);
                  void    *ptr;
                  size_t  mem_size;
                  static  list<MemCheck>          mcH;  // list head
                  static  unsigned long           total_memsize;  // total memory allocated
  };

  // Global variables ....
  list<MemCheck>          MemCheck::mcH;
  unsigned long           MemCheck::total_memsize = 0;

  MemCheck::MemCheck(void *aptr, size_t amem_size, char fname[], int lineno)
  {
          char func_name[100];
          FILE    *ferr = NULL;
          sprintf(func_name, "MemCheck() - File: %s Line: %d", fname, lineno);

          ferr = fopen(LOG_FILE, "a");
          if (ferr == NULL)
          {
                  fprintf(stdout, "\nWarning: Cannot open file %s\n", LOG_FILE);
                  fprintf(stderr, "\nWarning: Cannot open file %s\n", LOG_FILE);
                  #ifdef DEBUG_MEM
                          exit(-1);
                  #else
                          return;
                  #endif
          }

          // Search if the pointer already exists in the list...
          bool does_exist = false;
          list<MemCheck>::iterator iter1; // see file include/g++/stl_list.h
          //fprintf(ferr, "\n%s Before checking.. !!\n", func_name);
          if (MemCheck::mcH.empty() == true )
          {
                  //fprintf(ferr, "\n%s List is empty!!\n", func_name);
          }
          for (iter1 = MemCheck::mcH.begin(); iter1 != MemCheck::mcH.end(); iter1++)
          {
                  if (iter1 == NULL)
                  {
                          fprintf(ferr, "\n%s Iterator iter1 is NULL!!\n", func_name);
                          break;
                  }
                  if ( ((*iter1).ptr) == aptr)
                  {
                          does_exist = true;
                          fprintf(ferr, "\n%s Already exists!!\n", func_name);
                          fprintf(ferr, "\n%s Fatal Error exiting now ....!!\n", func_name);
                          #ifdef DEBUG_MEM
                                  exit(-1); //------------------------------------------------------------------>>>
                          #else
                                  return;
                          #endif
                          // Now change the mem size to new values...
                          // For total size - Remove old size and add new size
                          //fprintf(ferr, "\n%s total_memsize = %lu\n", func_name, (*iter1).total_memsize);
                          //fprintf(ferr, "\n%s mem_size = %u\n", func_name, (*iter1).mem_size);
                          //fprintf(ferr, "\n%s amem_size = %u\n", func_name, amem_size);
                          (*iter1).total_memsize = (*iter1).total_memsize + amem_size;
                          if ((*iter1).total_memsize > 0 )
                          {
                                  if ((*iter1).total_memsize >= (*iter1).mem_size )
                                          (*iter1).total_memsize = (*iter1).total_memsize - (*iter1).mem_size;
                                  else
                                  {
                                          fprintf(ferr, "\n\n%s total_memsize is less than mem_size!!", func_name);
                                          fprintf(ferr, "\n%s total_memsize = %lu", func_name, (*iter1).total_memsize);
                                          fprintf(ferr, "\n%s mem_size = %u", func_name, (*iter1).mem_size);
                                          fprintf(ferr, "\n%s amem_size = %u\n", func_name, amem_size);
                                  }
                          }
                          (*iter1).mem_size = amem_size;
                  }
          }

          // The pointer aptr does not exist in the list, so append it now...
          if (does_exist == false)
          {
                  //fprintf(ferr, "\n%s aptr Not found\n", func_name);
                  ptr = aptr;
                  mem_size = amem_size;
                  MemCheck::total_memsize += amem_size;
                  MemCheck::mcH.insert(MemCheck::mcH.end(), *this);
          }
          fclose(ferr);
  }

  static inline void call_check(void *aa, size_t tmpii, char fname[], int lineno)
  {
          MemCheck bb(aa, tmpii, fname, lineno);
          if (& bb);  // a dummy statement to avoid compiler warning msg.
  }

  static inline void remove_ptr(void *aa, char fname[], int lineno)
  {
          char    func_name[100];
          if (aa == NULL)
                  return;

          sprintf(func_name, "remove_ptr() - File: %s Line: %d", fname, lineno);
          FILE *ferr = NULL;
          ferr = fopen(LOG_FILE, "a");
          if (ferr == NULL)
          {
                  fprintf(stdout, "\nWarning: Cannot open file %s\n", LOG_FILE);
                  fprintf(stderr, "\nWarning: Cannot open file %s\n", LOG_FILE);
                  #ifdef DEBUG_MEM
                          exit(-1);
                  #else
                          return;
                  #endif
          }

          bool does_exist = false;
          if (MemCheck::mcH.empty() == true)
          {
                  //fprintf(ferr, "\n%s List is empty!!\n", func_name);
                  //fclose(ferr);
                  //return;
          }
          list<MemCheck>::iterator iter1; // see file include/g++/stl_list.h
          for (iter1 = MemCheck::mcH.begin(); iter1 != MemCheck::mcH.end(); iter1++)
          {
                  if (iter1 == NULL)
                  {
                          fprintf(ferr, "\n%s Iterator iter1 is NULL!!\n", func_name);
                          break;
                  }
                  if ( ((*iter1).ptr) == aa)
                  {
                          does_exist = true;
                          // Now change the mem size to new values...
                          // For total size - Remove old size
                          //fprintf(ferr, "\n%s total_memsize = %lu\n", func_name, (*iter1).total_memsize);
                          //fprintf(ferr, "\n%s mem_size = %u\n", func_name, (*iter1).mem_size);
                          if ((*iter1).total_memsize > 0 )
                          {
                                  if ((*iter1).total_memsize >= (*iter1).mem_size )
                                          (*iter1).total_memsize = (*iter1).total_memsize - (*iter1).mem_size;
                                  else
                                  {
                                          fprintf(ferr, "\n\n%s total_memsize is less than mem_size!!", func_name);
                                          fprintf(ferr, "\n%s total_memsize = %lu", func_name, (*iter1).total_memsize);
                                          fprintf(ferr, "\n%s mem_size = %u\n", func_name, (*iter1).mem_size);
                                  }
                          }
                          MemCheck::mcH.erase(iter1);
                          break;  // must break to avoid infinite looping
                  }
          }
          if (does_exist == false)
          {
                  //fprintf(ferr, "\n%s Fatal Error: - You did not allocate memory!! \n", func_name);
                  //fprintf(ferr, "\n%s The value passed is %s\n", func_name, (char *) aa);
          }
          else
                  //fprintf(ferr, "\n%s found\n", func_name);
          fclose(ferr);
  }

  static inline void call_free_check(void *aa, char *fname, int lineno)
  {
          char func_name[100];
          sprintf(func_name, "call_free_check() - File: %s Line: %d", fname, lineno);

          FILE *ferr = NULL;
          ferr = fopen(LOG_FILE, "a");
          if (ferr == NULL)
          {
                  fprintf(stdout, "\nWarning: Cannot open file %s\n", LOG_FILE);
                  fprintf(stderr, "\nWarning: Cannot open file %s\n", LOG_FILE);
                  #ifdef DEBUG_MEM
                          exit(-1);
                  #else
                          return;
                  #endif
          }

          bool does_exist = false;
          list<MemCheck>::iterator iter1; // see file include/g++/stl_list.h
          for (iter1 = MemCheck::mcH.begin(); iter1 != MemCheck::mcH.end(); iter1++)
          {
                  if (iter1 == NULL)
                  {
                          fprintf(ferr, "\n%s Iterator iter1 is NULL!!\n", func_name);
                          break;
                  }
                  if ( ((*iter1).ptr) == aa)
                  {
                          does_exist = true;
                          //fprintf(ferr, "\n%s iter1.mem_size = %u\n", func_name, (*iter1).mem_size);
                          //fprintf(ferr, "\n%s Total memory allocated = %lu\n",  func_name, (*iter1).total_memsize);
                          if ((*iter1).total_memsize > 0 )
                          {
                                  if ((*iter1).total_memsize >= (*iter1).mem_size )
                                          (*iter1).total_memsize = (*iter1).total_memsize - (*iter1).mem_size;
                                  else
                                  {
                                          fprintf(ferr, "\n\n%s total_memsize is less than mem_size!!", func_name);
                                          fprintf(ferr, "\n%s total_memsize = %lu", func_name, (*iter1).total_memsize);
                                          fprintf(ferr, "\n%s mem_size = %u", func_name, (*iter1).mem_size);
                                  }
                          }
                          MemCheck::mcH.erase(iter1);
                          break;  // must break to avoid infinite looping
                  }
          }
          if (does_exist == false)
          {
                  fprintf(ferr, "\n%s Fatal Error: free() - You did not allocate memory!!\n",
                                  func_name);
                  //fprintf(ferr, "\n%s The value passed is %s\n", func_name, (char *) aa);
                  fclose(ferr);
                  #ifdef DEBUG_MEM
                          exit(-1);
                  #else
                          return;
                  #endif
          }
          else
          {
                  //fprintf(ferr, "\n%s found\n", func_name);
          }
          fclose(ferr);
  }

  void local_print_total_memsize(char *fname, int lineno)
  {
          char func_name[100];
          sprintf(func_name, "local_print_total_memsize() - %s Line: %d", fname, lineno);

          FILE *ferr = NULL;
          ferr = fopen(LOG_FILE, "a");
          if (ferr == NULL)
          {
                  fprintf(stdout, "\nWarning: Cannot open file %s\n", LOG_FILE);
                  fprintf(stderr, "\nWarning: Cannot open file %s\n", LOG_FILE);
                  #ifdef DEBUG_MEM
                          exit(-1);
                  #else
                          return;
                  #endif
          }

          fprintf(ferr, "\n%s Total memory MemCheck::total_memsize = %lu\n",  func_name, MemCheck::total_memsize);
          fclose(ferr);
  }
  #else  //------------> DEBUG

  void local_print_total_memsize(char *fname, int lineno)
  {
          // This function is available whether debug or no-debug...
  }

  #endif // DEBUG

  void local_my_free(void *aa, char fname[], int lineno)
  {
          if (aa == NULL)
                  return;
          call_free_check(aa, fname, lineno);
          free(aa);
          aa = NULL;
  }

  // size_t is type-defed unsigned long
  void *local_my_malloc(size_t size, char fname[], int lineno)
  {
          size_t  tmpii = size + SAFE_MEM;
          void *aa = NULL;
          aa = (void *) malloc(tmpii);
          if (aa == NULL)
                  raise_error_exit(MALLOC, VOID_TYPE, fname, lineno);
          memset(aa, 0, tmpii);
          call_check(aa, tmpii, fname, lineno);
          return aa;
  }
  // size_t is type-defed unsigned long
  char *local_my_realloc(char *aa, size_t size, char fname[], int lineno)
  {
          remove_ptr(aa, fname, lineno);
          unsigned long tmpjj = 0;
          if (aa) // aa !=  NULL
                  tmpjj = strlen(aa);
          unsigned long tmpqq = size + SAFE_MEM;
          size_t  tmpii = sizeof (char) * (tmpqq);
          aa = (char *) realloc(aa, tmpii);
          if (aa == NULL)
                  raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno);

          // do not memset!! memset(aa, 0, tmpii);
          aa[tmpqq-1] = 0;
          unsigned long kk = tmpjj;
          if (tmpjj > tmpqq)
                  kk = tmpqq;
          for ( ; kk < tmpqq; kk++)
                  aa[kk] = 0;
          call_check(aa, tmpii, fname, lineno);
          return aa;
  }

  // size_t is type-defed unsigned long
  short *local_my_realloc(short *aa, size_t size, char fname[], int lineno)
  {
          remove_ptr(aa, fname, lineno);
          unsigned long tmpqq = size + SAFE_MEM;
          size_t  tmpii = sizeof (short) * (tmpqq);
          aa = (short *) realloc(aa, tmpii);
          if (aa == NULL)
                  raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno);
          // do not memset!! memset(aa, 0, tmpii);
          // Not for numbers!! aa[tmpqq-1] = 0;
          call_check(aa, tmpii, fname, lineno);
          return aa;
  }

  // size_t is type-defed unsigned long
  int *local_my_realloc(int *aa, size_t size, char fname[], int lineno)
  {
          remove_ptr(aa, fname, lineno);
          unsigned long tmpqq = size + SAFE_MEM;
          size_t  tmpii = sizeof (int) * (tmpqq);
          aa = (int *) realloc(aa, tmpii);
          if (aa == NULL)
                  raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno);
          // do not memset!! memset(aa, 0, tmpii);
          // Not for numbers!! aa[tmpqq-1] = 0;
          call_check(aa, tmpii, fname, lineno);
          return aa;
  }

  // size_t is type-defed unsigned long
  long *local_my_realloc(long *aa, size_t size, char fname[], int lineno)
  {
          remove_ptr(aa, fname, lineno);
          unsigned long tmpqq = size + SAFE_MEM;
          size_t  tmpii = sizeof (long) * (tmpqq);
          aa = (long *) realloc(aa, tmpii);
          if (aa == NULL)
                  raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno);
          // do not memset!! memset(aa, 0, tmpii);
          // Not for numbers!! aa[tmpqq-1] = 0;
          call_check(aa, tmpii, fname, lineno);
          return aa;
  }

  // size_t is type-defed unsigned long
  float *local_my_realloc(float *aa, size_t size, char fname[], int lineno)
  {
          remove_ptr(aa, fname, lineno);
          unsigned long tmpqq = size + SAFE_MEM;
          size_t  tmpii = sizeof (float) * (tmpqq);
          aa = (float *) realloc(aa, tmpii);
          if (aa == NULL)
                  raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno);
          // do not memset!! memset(aa, 0, tmpii);
          // Not for numbers!! aa[tmpqq-1] = 0;
          call_check(aa, tmpii, fname, lineno);
          return aa;
  }

  // size_t is type-defed unsigned long
  double *local_my_realloc(double *aa, size_t size, char fname[], int lineno)
  {
          remove_ptr(aa, fname, lineno);
          unsigned long tmpqq = size + SAFE_MEM;
          size_t  tmpii = sizeof (double) * (tmpqq);
          aa = (double *) realloc(aa, tmpii);
          if (aa == NULL)
                  raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno);
          // do not memset!! memset(aa, 0, tmpii);
          // Not for numbers!! aa[tmpqq-1] = 0;
          call_check(aa, tmpii, fname, lineno);
          return aa;
  }

  static void raise_error_exit(short mtype, short datatype, char fname[], int lineno)
  {
          if (mtype == MALLOC)
          {
                  fprintf(stdout, "\nFatal Error: malloc() failed!!");
                  fprintf(stderr, "\nFatal Error: malloc() failed!!");
          }
          else
          if (mtype == REALLOC)
          {
                  fprintf(stdout, "\nFatal Error: realloc() failed!!");
                  fprintf(stderr, "\nFatal Error: realloc() failed!!");
          }
          else
          {
                  fprintf(stdout, "\nFatal Error: mtype not supplied!!");
                  fprintf(stderr, "\nFatal Error: mtype not supplied!!");
                  exit(-1);
          }

          // Get current date-time and print time stamp in error file...
          char date_str[DATE_MAX_SIZE + SAFE_MEM];
          time_t tt;
          tt = time(NULL);
          struct tm *ct = NULL;
          ct = localtime(& tt); // time() in secs since Epoch 1 Jan 1970
          if (ct == NULL)
          {
                  fprintf(stdout, "\nWarning: Could not find the local time, localtime() failed\n");
                  fprintf(stderr, "\nWarning: Could not find the local time, localtime() failed\n");
          }
          else
                  strftime(date_str, DATE_MAX_SIZE , "%C", ct);
          FILE *ferr = NULL;
          char    filename[100];
          strcpy(filename, LOG_FILE);
          ferr = fopen(filename, "a");
          if (ferr == NULL)
          {
                  fprintf(stdout, "\nWarning: Cannot open file %s\n", filename);
                  fprintf(stderr, "\nWarning: Cannot open file %s\n", filename);
          }
          else
          {
                  // **************************************************
                  // ******* Do putenv in the main() function *********
                  //              char p_name[1024];
                  //              sprintf(p_name, "PROGRAM_NAME=%s", argv[0]);
                  //              putenv(p_name);
                  // **************************************************
                  char    program_name[200+SAFE_MEM];
                  if (getenv("PROGRAM_NAME") == NULL)
                  {
                          fprintf(ferr, "\n%sWarning: You did not putenv() PROGRAM_NAME env variable in main() function\n",
                                          date_str);
                          program_name[0] = 0;
                  }
                  else
                          strncpy(program_name, getenv("PROGRAM_NAME"), 200);

                  if (mtype == MALLOC)
                          fprintf(ferr, "\n%s: %s - Fatal Error - my_malloc() failed.", date_str, program_name);
                  else
                  if (mtype == REALLOC)
                  {
                          fprintf(ferr, "\n%s: %s - Fatal Error - my_realloc() failed.", date_str, program_name);
                          char dtype[50];
                          switch(datatype)
                          {
                                  case VOID_TYPE:
                                          strcpy(dtype, "char*");
                                          break;
                                  case CHAR_TYPE:
                                          strcpy(dtype, "char*");
                                          break;
                                  case SHORT_TYPE:
                                          strcpy(dtype, "char*");
                                          break;
                                  case INT_TYPE:
                                          strcpy(dtype, "char*");
                                          break;
                                  case LONG_TYPE:
                                          strcpy(dtype, "char*");
                                          break;
                                  case FLOAT_TYPE:
                                          strcpy(dtype, "char*");
                                          break;
                                  case DOUBLE_TYPE:
                                          strcpy(dtype, "char*");
                                          break;
                                  default:
                                          strcpy(dtype, "none*");
                                          break;
                          }
                          fprintf(ferr, "\n%s %s - Fatal Error: %s realloc() failed!!", date_str, program_name, dtype);
                  }

                  fprintf(ferr, "\n%s %s - Very severe error condition. Exiting application now....",
                                          date_str, program_name);
                  fclose(ferr);
          }

          exit(-1);
  }
  ______________________________________________________________________

  16.  ÷ E my_malloc.h

  Download mychar   α׷ ϳ tar.gz ȭϷ
  ٿε  ִ.  ȭ    ȭ
  'Text' Ÿ Ѵ.

  ______________________________________________________________________
  //*****************************************************************
  //۱ GNU/GPL    ̸ ̸  纻
  //ԽѾ Ѵ.
  //: Al Dev  ̸: alavoor@yahoo.com
  //*****************************************************************

  /*
  **      In your main() function put -
                  char p_name[1024];
                  sprintf(p_name, "PROGRAM_NAME=%s", argv[0]);
                  putenv(p_name);
                  print_total_memsize(); // in the beginning
                  ......
                  ......
                  print_total_memsize(); // in the end
  */

  /* Use zap instead of delete as this will be very clean!!
  ** Use do while to make it robust and bullet-proof macro
  */
  #define zap(x) do { if (x) { delete(x); x = 0; } } while (0)

  void *local_my_malloc(size_t size, char fname[], int lineno);

  char *local_my_realloc(char *aa, size_t size, char fname[], int lineno);
  short *local_my_realloc(short *aa, size_t size, char fname[], int lineno);
  void local_my_free(void *aa, char fname[], int lineno);

  void local_print_total_memsize(char fname[], int lineno);

  #define my_free(NM) (void) (local_my_free(NM, __FILE__, __LINE__))
  #define my_malloc(SZ) (local_my_malloc(SZ, __FILE__, __LINE__))
  #define my_realloc(NM, SZ) (local_my_realloc(NM, SZ, __FILE__, __LINE__))
  #define print_total_memsize() (void) (local_print_total_memsize(__FILE__, __LINE__))

  #ifdef DEBUG  //------------> DEBUG
  #else  //------------> DEBUG
  #define call_check(AA, BB, CC, DD) ((void) 0)
  #define call_free_check(AA, BB, CC) ((void) 0)
  #define remove_ptr(AA, CC, DD) ((void) 0)
  #endif //------------> DEBUG
  ______________________________________________________________________

  17.  ÷ F debug.h

  Download mychar   α׷ ϳ tar.gz ȭϷ
  ٿε  ִ.  ȭ    ȭ
  'Text' Ÿ Ѵ.
  ______________________________________________________________________
  //*****************************************************************
  //۱ GNU/GPL    ̸ ̸  纻
  //ԽѾ Ѵ.
  //: Al Dev  ̸: alavoor@yahoo.com
  //*****************************************************************

  #define print_log(AA, BB, CC, DD, EE) ((void) 0)

  #ifdef DEBUG

  #include <iostream>
  #include <string>
  //#include <assert.h>  // assert() macro which is also used for debugging

  const bool LOG_YES = true;  // print output to log file
  const bool LOG_NO = false;  // Do not print output to log file

  // Debugging code
  // Use debug2_ to output result to a log file

  #define debug_(NM, VL) (void) ( local_dbg(NM, VL, __FILE__, __LINE__) )
  #define debug2_(NM, VL, LOG_FILE) (void) ( local_dbg(NM, VL, __FILE__, __LINE__, LOG_FILE) )

  void local_dbg(char name[], char value[], char fname[], int lineno, bool logfile= false);
  void local_dbg(char name[], string value, char fname[], int lineno, bool logfile= false);
  void local_dbg(char name[], int value, char fname[], int lineno, bool logfile= false);
  void local_dbg(char name[], unsigned long value, char fname[], int lineno, bool logfile= false);
  void local_dbg(char name[], float value, char fname[], int lineno, bool logfile= false);
  void local_dbg(char name[], double value, char fname[], int lineno, bool logfile= false);

  #else  //--------> else

  #define debug_(NM, VL) ((void) 0)
  #define debug2_(NM, VL, LOG_FILE) ((void) 0)

  #endif // DEBUG
  ______________________________________________________________________

  18.  ÷ G debug.cpp

  Download mychar   α׷ ϳ tar.gz ȭϷ
  ٿε  ִ.  ȭ    ȭ
  'Text' Ÿ Ѵ.

  ______________________________________________________________________
  //*****************************************************************
  //۱ GNU/GPL    ̸ ̸  纻
  //ԽѾ Ѵ.
  //: Al Dev  ̸: alavoor@yahoo.com
  //*****************************************************************

  #ifdef DEBUG  // ONLY if DEBUG is defined then these functions below are needed

  #include "debug.h"
  //#include "log.h"

  // Variable value[] can be char, string, int, unsigned long, float, etc...

  void local_dbg(char name[], char value[], char fname[], int lineno, bool logfile) {
          if (value == NULL)
                  return;
          if (logfile == true)
                  print_log("\nDebug %s : Line: %d %s is = %s\n", fname, lineno, name, value);
          else
                  cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; }

  void local_dbg(char name[], string value, char fname[], int lineno, bool logfile) {
          if (logfile == true)
                  print_log("\nDebug %s : Line: %d %s is = %s\n", fname, lineno, name, value.c_str());
          else
                  cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value.c_str() << endl; }

  void local_dbg(char name[], int value, char fname[], int lineno, bool logfile) {
          if (logfile == true)
                  print_log("\nDebug %s : Line: %d %s is = %d\n", fname, lineno, name, value);
          else
                  cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; }

  void local_dbg(char name[], unsigned int value, char fname[], int lineno, bool logfile) {
          if (logfile == true)
                  print_log("\nDebug %s : Line: %d %s is = %u\n", fname, lineno, name, value);
          else
                  cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; }

  void local_dbg(char name[], long value, char fname[], int lineno, bool logfile) {
          if (logfile == true)
                  print_log("\nDebug %s : Line: %d %s is = %d\n", fname, lineno, name, value);
          else
                  cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; }

  void local_dbg(char name[], unsigned long value, char fname[], int lineno, bool logfile) {
          if (logfile == true)
                  print_log("\nDebug %s : Line: %d %s is = %u\n", fname, lineno, name, value);
          else
                  cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; }

  void local_dbg(char name[], short value, char fname[], int lineno, bool logfile) {
          if (logfile == true)
                  print_log("\nDebug %s : Line: %d %s is = %d\n", fname, lineno, name, value);
          else
                  cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; }

  void local_dbg(char name[], unsigned short value, char fname[], int lineno, bool logfile) {
          if (logfile == true)
                  print_log("\nDebug %s : Line: %d %s is = %u\n", fname, lineno, name, value);
          else
                  cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; }

  void local_dbg(char name[], float value, char fname[], int lineno, bool logfile) {
          if (logfile == true)
                  print_log("\nDebug %s : Line: %d %s is = %f\n", fname, lineno, name, value);
          else
                  cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; }

  void local_dbg(char name[], double value, char fname[], int lineno, bool logfile) {
          if (logfile == true)
                  print_log("\nDebug %s : Line: %d %s is = %f\n", fname, lineno, name, value);
          else
                  cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; }

  // You add many more here - value can be a class, ENUM, datetime, etc...

  #endif // DEBUG
  ______________________________________________________________________

  19.  ÷ H Makefile

  Download mychar   α׷ ϳ tar.gz ȭϷ
  ٿε  ִ.  ȭ    ȭ
  'Text' Ÿ Ѵ.

  ______________________________________________________________________
  #//*****************************************************************
  #//۱ GNU/GPL    ̸ ̸  纻
  #//ԽѾ Ѵ.
  #//: Al Dev  ̸: alavoor@yahoo.com
  #//*****************************************************************

  .SUFFIXES: .pc .cpp .c .o

  CC=gcc
  CXX=g++

  MAKEMAKE=mm
  LIBRARY=libmychar.a
  DEST=/home/myname/lib

  # To build the library, and main test program  uncomment line below :-
  #MYCFLAGS=-O -Wall

  # To test without debug trace uncomment line below:-
  #MYCFLAGS=-g3 -Wall

  # To enable 'full debug ' tracing uncomment line below:-
  MYCFLAGS=-g3 -DDEBUG -Wall

  #PURIFY=purify -best-effort

  SRCS=my_malloc.cpp mychar.cpp debug.cpp example_mychar.cpp
  HDR=my_malloc.h  mychar.h debug.h
  OBJS=my_malloc.o mychar.o debug.o example_mychar.o
  EXE=mychar

  # For generating makefile dependencies..
  SHELL=/bin/sh

  CPPFLAGS=$(MYCFLAGS) $(OS_DEFINES)
  CFLAGS=$(MYCFLAGS) $(OS_DEFINES)

  #
  # If the libmychar.a is in the current
  # directory then use -L. (dash L dot)
  MYLIBDIR=-L$(MY_DIR)/libmy -L.

  ALLLDFLAGS= $(LDFLAGS)  $(MYLIBDIR)

  COMMONLIBS=-lstdc++ -lm
  MYLIBS=-lmychar
  LIBS=$(COMMONLIBS)  $(MYLIBS)

  all: $(LIBRARY) $(EXE)

  $(MAKEMAKE):
          @rm -f $(MAKEMAKE)
          $(PURIFY) $(CXX) -M  $(INCLUDE) $(CPPFLAGS) *.cpp > $(MAKEMAKE)

  $(EXE): $(OBJS)
          @echo "Creating a executable "
          $(PURIFY) $(CC) -o $(EXE) $(OBJS) $(ALLLDFLAGS) $(LIBS)

  $(LIBRARY): $(OBJS)
          @echo "\n***********************************************"
          @echo "   Loading $(LIBRARY) ... to $(DEST)"
          @echo "***********************************************"
          @ar cru $(LIBRARY) $(OBJS)
          @echo "\n "

  .cpp.o: $(SRCS) $(HDR)
  #       @echo "Creating a object files from " $*.cpp " files "
          $(PURIFY) $(CXX) -c  $(INCLUDE) $(CPPFLAGS) $*.cpp

  .c.o: $(SRCS) $(HDR)
  #       @echo "Creating a object files from " $*.c " files "
          $(PURIFY) $(CC) -c $(INCLUDE) $(CFLAGS) $*.c

  clean:
          rm -f *.o *.log *~ *.log.old *.pid core err a.out lib*.a afiedt.buf
          rm -f $(EXE)
          rm -f $(MAKEMAKE)

  #%.d: %.c
  #       @echo "Generating the dependency file *.d from *.c"
  #       $(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< | sed '\''s/$*.o/& $@/g'\'' > $@'
  #%.d: %.cpp
  #       @echo "Generating the dependency file *.d from *.cpp"
  #       $(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< | sed '\''s/$*.o/& $@/g'\'' > $@'

  # Must include all the c flags for -M option
  #$(MAKEMAKE):
  #       @echo "Generating the dependency file *.d from *.cpp"
  #       $(CXX) -M  $(INCLUDE) $(CPPFLAGS) *.cpp > $(MAKEMAKE)

  include $(MAKEMAKE)
  #include $(SRCS:.cpp=.d)
  #include $(SRCS:.c=.d)
  ______________________________________________________________________

