Monday, May 16, 2011

Make libraries for yourself


Do you program on a daily basis? Do you find yourself using the same methods, classes or constants in multiple programs? Do you find yourself copying macro's constantly? Well use a library file instead.. Most compiler's I have used allow you to make a .cpp or .c(etc) file and then compile it and link it into any application that contains the corresponding .h file with the function or class declarations. For example- I have produced nearly 30 METHOD headers for my programs. One might deal with input/output manipulations. Another might define iterator macro's. Yet another might deal with variable manipulation or streaming. Then include them all into yet another header file and include it in all of your work, so you don't have to redefine these methods/variables/macro's in seperate files.
:: as a note :: The extraneous header files must be saved into your includes folder(for dev-cpp) or into the includes directory.


Write it out on paper

Think before you code and write the entire idea or the logic of solving a particular problem on paper; doing so would prevent lots of logical errors. This technique also works when you are not able to figure out why the logic is not working.

Use templates to prevent memory leakage

Make a class template to create an instance of a desired class and in the destructor of the class template, delete the item the pointer points to. In this way, the programmer won't have to worry about freeing the memory.

Flowcharts


Use a flowchart to represent the logic of your program before coding.This will reduce lot of redundancy and helps improve your logic. In fact, even if you don't use a flow chart, but sure to spend some time thinking about your program design before diving in and writing code.

Initialize all variables before use

Always remember to initialize variables with default values. This is not only a good programming practice but helps prevent logical errors. For instance, it is very helpful to set all pointers to NULL when you declare them; that way, if you accidentally use an un initialized pointer, you will get a segmentation fault rather than weird memory errors that appear random and are difficult to trace to the root cause.

Common Optimization Tips

The first and most important thing to remember when optimizing a program is to know your compiler's options. Most of the time, more can be done just by adjusting compiler options than by anything else; it's just that many programmers aren't familiar with the different switches available. Since most compilers have different switches, I'd suggest looking through your compiler's help docs to see which switches would be best for you. If unsure about a switch, try them to see if they are beneficial -- if not, then don't use them (make sure to note any possible side effects in the docs for that switch).

Other hand optimizations: (keep in mind that premature optimization can be worse than no optimization at all - never assume that an optimization is beneficial because every instance of an optimization may be different)

* For loops - If the order of the iterations in a for loop does not matter and you are starting from zero, then replace:

for(i = 0; i < max; i++) {
list[i] = 0;
}

with:

for(i = max; i--;) {
list[i] = 0;
}

It will be slightly faster and should be 2 bytes smaller -- not much in and of itself, but spread over a large program or in many nested for loops and it does make a difference.

* Declare functions called only once or twice as "static inline". Static inline functions can usually be inlined better than plain inline ones. Also, the compiler will usually only inline if it will produce better code.

* If you have a lot of global variables, try putting each one in a typedef struct and then using a global register variable to access them. Then, access them through the global register variable as a pointer like:

typedef struct {
data vars...
} GlobalVars;

register GlobalVars *g asm(\\"a4\\");

and allocate/initialize g to be used throughout your program, accessing the data as g->data.

* Think about unrolling speed critical or smaller loops.

* If you have several memory allocations to do, try allocating with one bulk malloc instead of several smaller ones; then split up the appropriate pointers afterwards. Having many memory allocations and the associated error checks that accompany them may not be as efficient as one bulk allocation. Keep in mind, though, that by allocating memory in one large chunk instead of several smaller chunks, the allocation is more likely to fail, especially if you are dealing with large amounts of memory or are running on an older system.

* It may be worth it to learn some assembly, even if it is just for the purpose of inline assembly for speed critical parts where your program gets bottlenecked. Though compilers are closing the gap between hand-optimized assembly and C/C++, they are still not at par with them. Using inline assembly is sound advice, but you also have to remember that novice-written assembly will more than likely turn out to be less efficient than comparable compiler-outputted code.

* And last, but definitely not least, optimizations are pointless if you are using an inefficient algorithm!
{stupid metaphor} Walking 50 miles, even if you optimize your route, will still be slower than driving 50 miles on unoptimized, curvy roads {/stupid metaphor}
Walking (inefficient algorithm), even if optimized, will not be as fast as driving (more efficient algorithm).

Turn on all compiler warnings

When compiling projects, turn on all compiler warnings (e.g., when using gcc or g++, use the -Wall flag) to see all warnings to avoid later problems. Fixing all the warnings will allow you to have the clearest and least buggy code you can have.

Keep a cool head when programming

Whenever you are ready to hop on your computer and program, it's always best to stay calm. If you hop on your computer with too many emotions, such as anxiety, nervousness, and a hot-temper, you will not be able to focus on what your doing. So what I like to do is, keep everything quiet. That way I can focus on the program, and not anything else.

match the out side world ideas to logical designing

While designing of any module of an application ,you can observe the outside world from the s/w world .
For example an address book application to be built up, rather going to design it directly -- you can observe your daily routine and keep track of your daily address book usage.

Try to give them a proper order then convert it into logical steps.

Finally, that will give you the proper
picture of the module.

Cool tip ... try to be nearer to the nature.

Goto vs. Higher-level control structures

Some very simple programming languages allow you to control the flow of your program with the goto keyword. You simply place a label somewhere in your program, and then can can jump to that point in your code anytime you like by following goto with that keyword. Like so:

goto myLabel
...
myLabel:
/* code */

In these simple and limited programming languages, goto may be used quite commonly, and this feature is included in C/C++ too. It is however, considered extremely bad practice.

The reason for this is simply that there are better alternatives. C and C++ provide more advanced control structures like various types of functions and loops, which not only make it easy to code a certain behavior, but safer. goto is still sometimes used for customized control, like breaking out of heavily nested loops.

It has been said that if your program does indeed require the use of goto, you should probably be redesigning the whole program to fix it properly instead of using a quick fix like goto.

If in doubt, don't use goto

The many meanings of NULL

There are three uses of the word null:

1. A null pointer is a pointer which doesn't point anywhere.

2. A NULL macro is used to represent the null pointer in the source code. It has a value of 0 associated with it.

3. The ASCII NULL character has all its bits as 0 but doesn't have any relationship with the null pointer!

Turn off optimization when debugging

This is an addendum to the tip titled "Turn on all compiler warnings" that occured on this list some time ago.

Turn off all optimization using -O0 when compiling with gcc or g++. This will help in doing away with any errors that code optimization might introduce.

Use const variables as function parameters


Use const variable as function parameter whenever is possible.

Example:
foo(const char *value)
{
*value = 10; // Error, because it is a constant.
}

The reason you want to pass a const variable into a function is to guarantee the function is not able to change the value that the pointer is pointing at.

It also helps readability because by reading the pass-in parameter of the function, you knew that the const char *value will not change.





Effective Modularity in Programming


If you are doing a C project which requires modules and which is supposed to be ported in future, then it is better to do like this.

Write those code segments which are machine independent in one module and those which are machine dependent in another module.

While porting the program to another type of machine it is easy to fix errors if you do like this.

Loop condition

Try to put i != 0 rather than i
i != 0 is compared very fast on some architecture.

Pointer Memory allocation

When ever you deallocate the memory reset the pointer to NULL to make sure that you do not use a dangling pointer. For example:

free(Session);
Session=NULL;

Now if you try to use Session, then it will crash your program immediately, rather than using invalid memory, which will cause very hard-to-find problems.

Compiler tip

Get all three of these compilers:
1) MS vc++
2) Dev - c++
3) Borland 5.5
and the newest DirectX you can get.
This covers basically all types of ISO standards; you should be able to compile anything in one of these compilers. When I started with dev - c++ most graphic programs I wrote did not compile; then, when I got Ms vc++ + DirectX lots of other things compiled but it didn't recognise REGS. Then when I got Borland--well, since then, everything I've written has compiled.

Fix all compiler warnings


When you're first starting out,you have no choice but to solve the errors detected by the compiler,but you might neglect the warnings given by the compiler!

Warnings are cases where the compiler understands what your program is doing,and thinks that it's probably not doing what YOU want it to do. The compiler is pretty smart, so it's usually right.

For example,with code like this:

int getMultiple(int x,int y)
{
x*y;
}

you might have warning that says,"function should return a value"


This is because you forgot to return the result of the multiplication. Many compiler warnings are similarly valuable.

In general,you should compile with as many compiler warnings as possible(-Wall on GCC for example)and fix all of them. You can force yourself to do so if you compile with-Werror on GCC,which will cause GCC to treat all warnings as errors.

var++ & ++var

As far as possible one should use ++i and --i rather than i++ or i--. In a nutshell one should always use the pre increment/decrement forms rather than the post ones.The reason being, post increment retains the old value (usually in a temporary variable) and usually one does not end up using the old value, so that temp variable ends up by just wasting instructions.

Thus always use the pre-increment/decrement statements rather than the post ones. This is most important for complex types like iterators. It tends to be mostly irrelevant for integers

Tips for C

1)Never ever forget to initialize the pointer. This may be simple and easy known stuff but here I would like to add it as an embedded system developer that this was the main cause of many bugs.
2) Also never change the pointer variable itself unless & until you need to change the pointer.
3) Also monitor that the pointers are not overlapping if not pointing to same memory location range.

Print ip, email addressess or urls found in text


#include < stdio.h>#include < regex.h>
#include < ctype.h>
#include < getopt.h>
#include < stdlib.h>
#include < string.h>
#include < locale.h>
#include < sys/types.h>

#define PACKAGE    "miep"
#define VERSION    "1.0.0"

#define IPEXPR    "([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})"
#define EMEXPR    ".*@.*\\.([a-zA-Z]{1,3})$"
#define UREXPR    "(href|src)="

void print_ipadd(FILE *fp);
void print_email(FILE *fp);
void print_url(FILE *fp);
void print_help(int exval);

int main(int argc, char *argv[]) {
 FILE *fp = stdin;
 int opt = 0;
 int em_set = 0;
 int ip_set = 0;
 int ur_set = 0;

 setlocale(LC_ALL, "");

 while((opt = getopt(argc, argv, "hvieu")) != -1) {
  switch(opt) {
   case 'h':
    print_help(0);
    break;
   case 'v':
    fprintf(stdout, "%s %s\n", PACKAGE, VERSION);
    exit(0);
    break;
   case 'i':
    ip_set = 1;
    break;
   case 'e':
    em_set = 1;
    break;
   case 'u':
    ur_set = 1;
    break;
   case '?':
    fprintf(stderr, "%s: Error: No such option `%c'\n\n", PACKAGE, optopt);
    print_help(1);
    break;
  } /* switch */
 } /* while */

 if(argc == 1 || (ip_set == 0 && em_set == 0 && ur_set == 0))
  print_help(1);

 if((optind - argc) == 0) {
  if(em_set == 1)
   print_email(fp);
  else if(ip_set == 1)
   print_ipadd(fp);
  else
   print_url(fp);
 } else {
  /* loop over remaining args [files] */
  for(; optind < argc; optind++) {
   if(freopen(argv[optind], "r", fp) == NULL) {
    perror(argv[optind]);
    continue;
   }

   if(em_set == 1)
    print_email(fp);
   else if(ip_set == 1)
    print_ipadd(fp);
   else
    print_url(fp);
  } /* for */
 } /* else */

 fclose(fp);
 return 0;
}

void print_ipadd(FILE *fp) {
 char line[1024];
 char *address = NULL;
 char delim[] = ",:;`/\"+-_(){}[]<>*&^%$#@!?~/|\\= \t\r\n";
 int retval = 0;
 regex_t re;

 if(regcomp(&re, IPEXPR, REG_EXTENDED) != 0)
  return;

 while((fgets(line, 1024, fp)) != NULL) {
  if(strchr(line, '.') == NULL)
   continue;

  address = strtok(line, delim);
  while(address != NULL) {
   if(strlen(address) <= 15)
    if((retval = regexec(&re, address, 0, NULL, 0)) == 0)
     printf("%s\n", address);

   address = strtok(NULL, delim);
  } /* while */
 } /* while */
} /* print_ipadd */

void print_email(FILE *fp) {
 char address[256];
 char line[1024];
 char *ptr1 = NULL;
 char *ptr2 = NULL;
 int retval = 0;
 regex_t re;

 if(regcomp(&re, EMEXPR, REG_EXTENDED) != 0)
  return;

 while((fgets(line, 1024, fp)) != NULL) {
  if(strchr(line, '@') == NULL && strchr(line, '.') == NULL)
   continue;

  for(ptr1 = line, ptr2 = address; *ptr1; ptr1++) {
   if(isalpha(*ptr1) || isdigit(*ptr1) || strchr(".-_@", *ptr1) != NULL)
    *ptr2++ = *ptr1;
   else {
    *ptr2 = '\0';

    if(strlen(address) >= 6 && strchr(address, '@') != NULL &&
       strchr(address, '.') != NULL)
     if((retval = regexec(&re, address, 0, NULL, 0)) == 0)
      printf("%s\n", address);

    ptr2 = address;
   } /* else */
  } /* for */
 } /* while */
} /* print_email */

void print_url(FILE *fp) {
 char line[1024];
 char delim[] = "<> \t\n";
 char *url = NULL;
 int retval = 0;
 regex_t re;

 if(regcomp(&re, UREXPR, REG_ICASE|REG_EXTENDED) != 0)
  return;

 while((fgets(line, 1024, fp)) != NULL) {
  url = strtok(line, delim);
  while(url != NULL) {
   if((retval = regexec(&re, url, 0, NULL, 0)) == 0)
    printf("%s\n", url);

   url = strtok(NULL, delim);
  } /* while */
 } /* while */
} /* print_url */

void print_help(int exval) {
 printf("%s,%s print e-mail, urls or ip addresses from in textdata\n", PACKAGE, VERSION);
 printf("%s [-h] [-v] [-i] [-e] [-u] FILE...\n\n", PACKAGE);

 printf(" -h        print this help and exit\n");
 printf(" -v        print version and exit\n\n");

 printf(" -i        print ip addresses\n");
 printf(" -e        print e-mail addresses\n");
 printf(" -u        print urls\n\n");

 exit(exval);
}

C > Small Programs sample source codes(Pick random values)


//Pick random values

#include < time.h>
#include < stdio.h>
#include < fcntl.h>
#include < string.h>
#include < stdlib.h>
#include < unistd.h>
#include < getopt.h>
#include < limits.h>
#include < sys/stat.h>
#include < sys/types.h>

#define PACKAGE "raval"
#define VERSION "0.0.1"

/* status epilepticus, print help and exit with `exval' */
void print_help(int exval);
/* picks a radom value withing range low-high*/
int get_rand_val(int low, int high);
/* ! definitely not cryptographic secure ! */
/* value returned seeds the rand() function */
unsigned time_seed(void);

int main(int argc, char *argv[]) {
 int opt = 0;          /* holds option */
 int max = 10;         /* upper limit */
 int min = 0;          /* minimum limit */
 int many = 1;         /* the number of numbers to pick ... */
 char *ptr = NULL;     /* separator for number range */

 while((opt = getopt(argc, argv, "hvn:r:")) != -1) {
  switch(opt) {
   case 'h':
    print_help(0);
    break;
   case 'v':
   exit(0);
   case 'n':
    many = atoi(optarg);
    break;
   case 'r':
    if((ptr = strchr(optarg, ':')) == NULL) {
     fprintf(stderr, "%s: Error - range `LOW:HIGH'\n\n", PACKAGE);
     print_help(1);
    } else {
     ptr++, max = atoi(ptr);
     ptr--, ptr = '\0';
     min = atoi(optarg);
     if(min >= max || min < 0 || max < 0) {
      fprintf(stderr, "%s: Error - range `LOW:HIGH'\n\n", PACKAGE);
      print_help(1);
     }
    }
    break;
   case '?':
    fprintf(stderr, "%s: Error - No such option: `%c'\n\n", PACKAGE, optopt);
    print_help(1);
   case ':':
    fprintf(stderr, "%s: Error - option `%c' needs an argument\n\n", PACKAGE, optopt);
    print_help(1);
  }
 }

 /* first seed the random function */
 srand((time_seed()));

 /* print the random values */
 for(; many > 0; many--)
  printf("%4d\n", get_rand_val(min, max));

 return 0;
}

/* picks a radom value withing range low-high*/
int get_rand_val(int low, int high) {
 int k = 0;
 double d = 0;

 d = (double)rand() / ((double)RAND_MAX + 1);
 k = (int)(d * (high - low + 1));

 return(low + k);
}

/* ! definitely not cryptographic secure ! */
/* value returned seeds the rand() function */
unsigned time_seed(void) {
 int retval = 0;
 int fd;

 /* just in case open() fails.. */
 if(open("/dev/urandom", O_RDONLY) == -1) {
  retval = (((int)time(NULL)) & ((1 << 30) - 1)) + getpid();
 } else {
  read(fd, &retval, 4);
  /* positive values only */
  retval = abs(retval) + getpid();
  close(fd);
 }

 return retval;
}

void print_help(int exval) {
 printf("%s,%s print a random number\n", PACKAGE, VERSION);
 printf("Usage: %s OPTION...\n\n", PACKAGE);

 printf(" -h         print this help and exit\n");
 printf(" -v         print version and exit\n\n");

 printf(" -n INT     return `INT' numbers\n");
 printf(" -r INT:INT keep the number within range `LOW:HIGH',\n");
 printf("            default=(1:10)\n\n");


 exit(0);
}


C > Small Programs sample source codes(Positional notation of numbers)


//Positional notation of numbers

#include < stdio.h>
#include < math.h>

#define PACKAGE "digits"

int number_of_digits(int x);
void print_help(void);

int main(int argc, char *argv[]) {
 int n;             /* input; the number to convert */
 short base;        /* input; base to which we will convert n */
 short rhdigit;     /* right-hand digit of n-prime */
 int power;         /* loop */

 if(argc != 3) {
  print_help();
  return 1;
 } else {
  sscanf(argv[1], "%d", &n);
  if(n < 1) {
   fprintf(stderr, "%s: Error: Number must be greater than 0.\n", PACKAGE);
   return 1;
  }

  sscanf(argv[2], "%hi", &base);
  if(base < 2 || base > 10) {
   fprintf(stderr, "%s: Error: Base is not in required range.", PACKAGE);
   return 1 ;
  }
 } /* else */

 printf("The number %d, is %d wide, ", n, number_of_digits(n));
 printf("and contains the numbers: ");

 /*
 // Generate digits of converted number, right to left.
 */
 for(power = 0; n != 0; power++) {
  rhdigit = n % base;         /* Isolate right-hand digit of n. */
  n /= base;                  /* then eliminate right-hand digit. */

  printf("%hi ", rhdigit);
 }

 printf("\n");
 return 0;
}

int number_of_digits(int x) {
 return x ? (int)(log10((double)(abs(x))))+1 : 1;
}

void print_help(void) {
 fprintf(stdout, "Usage  : %s [NUMBER] [BASE]\n", PACKAGE);
 fprintf(stdout, "Example: %s 4591 10\n", PACKAGE);
}

C > Small Programs sample source codes(Print several types of alphabets)

//Print several types of alphabets

#include < stdio.h>
#include < ctype.h>
#include < getopt.h>
#define PACKAGE "alphabet"
#define VERSION "0.0.5"
/*
// `0' westeren, `1' phonetic, `2' greek `3' hebrew
// `4' phoenician `5' arab
*/
static int type = 0;
/* all output upper case */
static int upper = 0;
/* recursive, output until killed */
static int recur = 0;

/* phonetic alphabet */
const char *palpha[]= { "alpha", "bravo", "charlie", "delta",
"echo", "foxtrot", "golf", "hotel",
"india", "juliet", "kilo", "lima",
"mike", "november", "oscar", "papa",
"quebec", "romeo", "sierra", "tango",
"uniform", "victor", "whisky", "x-ray",
"yankee", "zulu" };

/* lower case greek alphabet */
const char *galpha[]= { "alpha", "beta", "gamma", "delta",
"epsilon", "zeta", "eta", "theta",
"iota", "kappa", "lambda", "mu",
"nu", "xi", "omicron", "pi",
"rho", "sigma", "tau", "upsilon",
"phi", "chi", "psi", "omega" };

/* lower case hebrew alphabet */
const char *halpha[]= { "tet", "chet", "zayin", "vav",
"he", "dalet", "gimel", "bet",
"alef", "samech", "nun", "nun",
"mem", "mem", "lamed", "khaf",
"kaf", "yod", "tav", "shin",
"resh", "qof", "tzade", "tzade",
"fe", "pe", "ayin" };

/* lower case phoenician alphabet */
const char *nalpha[]= { "aleph", "beth", "gimel", "daleth",
"he", "waw", "heth", "yodh",
"kaph", "lamedh", "mem", "nun",
"ayin", "pe", "qoph", "resh",
"sin", "taw", "waw", "samekh",
"zayin" };

/* lower case arab alphabet */
const char *aalpha[]= { "xaa", "haa", "jiim", "th!aa",
"taa", "baa", "alif", "saad",
"shiin", "siin", "zaay", "raa",
"thaal", "daal", "qaaf", "faa",
"ghayn", "ayn", "th:aa", "taa",
"daad", "yaa", "waaw", "haa",
"nuun", "miim", "laam", "kaaf" };

/* status epilepticus, and die with `exval' */
void print_help(int exval);
/* print the specified alphabet */
void print_alphabet(void);

int main(int argc, char *argv[]) {
int opt = 0;

/* option parser */
while((opt = getopt(argc, argv, "hvpgwiaru")) != -1) {
switch(opt) {
case 'h': /* print help and exit */
print_help(0);
case 'v': /* print version and exit */
exit(0);
case 'p': /* print the phonetic alphabet */
type = 1;
break;
case 'g': /* print the lower case greek alphabet */
type = 2;
break;
case 'w': /* print the lower case hebrew alphabet */
type = 3;
break;
case 'i': /* print the lower case phoenician alphabet */
type = 4;
break;
case 'a': /* print the lower case arab alphabet */
type = 5;
break;
case 'r': /* print the alphabet repeatedly until killed */
recur = 1;
break;
case 'u': /* print all output upper case */
upper = 1;
break;
case '?': /* unkown option */
fprintf(stderr, "%s: Error - no such option `%c'\n\n", PACKAGE, optopt);
print_help(1);
break;
} /* switch */
} /* while */

/* prints the selected alphabet */
print_alphabet();

return 0;
}

/* prints the selected alphabet */
void print_alphabet(void) {
const char *ptr = NULL;
int i = 0;

/* western alphabet */
if(type == 0) {
if(upper == 0)
for(i = 97; i <= 122; i++)
printf("%c\n", i);
else
for(i = 65; i <= 90; i++)
printf("%c\n", i);
/* phonetic alphabet */
} else if(type == 1) {
if(upper == 0) {
for(i = 0; i < 26; i++)
printf("%s\n", palpha[i]);
} else {
for(i = 0; i < 26; i++) {
ptr = palpha[i];
while(*ptr)
printf("%c", toupper(*ptr++));
printf("\n");
} /* for */
} /* else */
/* greek alphabet */
} else if(type == 2) {
if(upper == 0) {
for(i = 0; i < 24; i++)
printf("%s\n", galpha[i]);
} else {
for(i = 0; i < 24; i++) {
ptr = galpha[i];
while(*ptr)
printf("%c", toupper(*ptr++));
printf("\n");
} /* for */
} /* else */
} else if(type == 3) {
if(upper == 0) {
for(i = 0; i < 27; i++)
printf("%s\n", halpha[i]);
} else {
for(i = 0; i < 27; i++) {
ptr = halpha[i];
while(*ptr)
printf("%c", toupper(*ptr++));
printf("\n");
} /* for */
} /* else */
} else if(type == 4) {
if(upper == 0) {
for(i = 0; i < 21; i++)
printf("%s\n", nalpha[i]);
} else {
for(i = 0; i < 21; i++) {
ptr = nalpha[i];
while(*ptr)
printf("%c", toupper(*ptr++));
printf("\n");
} /* for */
} /* else */
} else if(type == 5) {
if(upper == 0) {
for(i = 0; i < 28; i++)
printf("%s\n", aalpha[i]);
} else {
for(i = 0; i < 28; i++) {
ptr = aalpha[i];
while(*ptr)
printf("%c", toupper(*ptr++));
printf("\n");
} /* for */
} /* else */
} /* else if */

if(recur == 1)
print_alphabet();
else
return;
}

/* status epilepticus, and die with `exval' */
void print_help(int exval) {
printf("%s,%s prints different alphabets\n", PACKAGE, VERSION);
printf("Usage: %s [-h] [-v] [-p] [-g] [-w] [-i] [-a] [-r] [-u]\n\n", PACKAGE);

printf(" Startup:\n");
printf(" -h print this help and exit\n");
printf(" -v print version and exit\n\n");

printf(" Alphabet:\n");
printf(" -p print the phonetic alphabet\n");
printf(" -g print the greek alphabet\n");
printf(" -w print the hebrew alphabet\n");
printf(" -i print the phoenician alphabet\n");
printf(" -a print the arab alphabet\n\n");

printf(" Output:\n");
printf(" -r print the alphabet repeatedly until killed\n");
printf(" -u print all output in upper case\n\n");

printf(" Per default the Westeren alphabet is printed\n");
exit(exval);
}

Translate all DOT'S -056, except for the last one



#include < stdio.h>
#include < getopt.h>
#include < string.h>

#define PACKAGE "dedot"
#define VERSION "1.0.0"
#define MAXLINE 1024

void print_help(int exval);

int main(int argc, char *argv[]) {
char line[MAXLINE];
char *ptr = NULL; /* points to the last dot */
char sub_char[1]; /* substidute char */
int sub_set = 0; /* substitude set ? */
int all_flag = 0; /* print all lines, even the ones not subject to change */
/* 1=on, 0=off */
int i = 0;
int opt;

while((opt = getopt(argc, argv, "hac:")) != -1) {
switch(opt) {
case 'h':
print_help(0);
break;
case 'a':
all_flag = 1;
break;
case 'c':
sub_set = 1;
strncpy(sub_char, optarg, 1);
break;
case ':':
fprintf(stderr, "%s: Option `%c' needs an argument `-c CHAR' ?\n\n",
PACKAGE, optopt);
print_help(1);
break;
case '?':
fprintf(stderr, "%s: No such option `%c'\n\n", PACKAGE, optopt);
print_help(1);
break;
} /* switch */
} /* while */

while((fgets(line, 1024, stdin)) != NULL) {
if((ptr = strrchr(line, '.')) == NULL) {
if(all_flag == 1)
printf("%s", line);

continue;
}

for(i = 0; i < strlen(line); i++)
if(sub_set == 1 && line[i] == '.' && &line[i] != ptr)
printf("%c", sub_char[0]);
else if(line[i] != '.' || &line[i] == ptr)
printf("%c", line[i]);
}

return 0;
}

void print_help(int exval) {
printf("%s,%s remove every dot `.' exept for the last one\n", PACKAGE, VERSION);
printf("%s [-h] [-c CHAR]\n\n", PACKAGE);

printf(" -h print this help and exit\n");
printf(" -c CHAR substitude all dots EXCEPT the last one with character `CHAR'\n");
printf(" -a print all lines, even the ones which are not subject of change\n\n");

exit(exval);
}

Reading The Master Boot Record & FAT of a Normal 1.44 MB Floppy disk (Mini Project)

#include<>
#include<>
#include
#include

char buffer[512],buf[512],c;

/*Procedure To read the content of MBR and place it ina file*/
char *mbr()
{
FILE *f;

strcpy(buffer,"The MBR is not Good");

_BX=(unsigned)buffer; //Reading The MBR
_ES=_DS;
_AX=0x0201;
_CX=0x0001; // Head:00 Track:00 Sector:01
_DX=0x0000;
geninterrupt(0x13);

if(strcmp(buffer,"The MBR is not Good")>0)
{
f=fopen("MBR.DAT","wb+");
fwrite(buffer, sizeof(buffer), 1, f); // Wiriting Content into a file
fclose(f);
}
else
printf("

Not A Good Floppy Disk");

return(buffer);

}


char *FAT_table()
{

FILE *f;
char *bu;
strcpy(buffer,"PART I is not good");
strcpy(buf,"PART II is not good");

printf("


Loading Frist Part
");

_BX=(unsigned) buffer;
_ES=_DS;
_AX=0x0201; //Reading Frist Part FAT table
_CX=0x0002; // Head:00 Track:00 Sector:02
_DX=0x0000;

geninterrupt(0x13);

printf(" PRESS A KEY TO CONTINUE
");
getch();
printf(" Loading Second Part");

_BX=(unsigned) buf;
_ES=_DS;
_AX=0x0201; // Reading Second Part of FAT
_CX=0x0003; // Head:00 Track:00 Sector:03
_DX=0x0000;

geninterrupt(0x13);

if(strcmp(buffer,"PART I is not good")>0&&strcmp(buf,"PART II is not
good")>0)
{
f=fopen("FAT.DAT","wb+");

fwrite(buffer,sizeof(buffer),1,f);
fwrite(buf,sizeof(buf),1,f); // Writing the content in a file
fclose(f);
}
else
printf("

Not a Good Disk");

strcat(buffer,buf);
strcpy(bu,buffer);
textcolor(15);
cprintf("


Finished Loading");
return(bu);
}

void main()
{
x:clrscr();

textcolor(15);
cprintf("





INSERT FLOPPY IN
A:
DRIVE");
cprintf("


PRESS 'ENTER' TO READ THE MBR & FAT
CONTENT");

if((c=getch())==13)// To press 'Enter' key
{
mbr();FAT_table();
}
else
goto x;
getch();
}

C > Small Programs sample source codes(WAV file player)

WAV file player

/WARNING: You need a HUGE memory model to run this.

#include "ALLOC.H"
#include "DOS.H"
#include "CONIO.H"
#include "STDIO.H"

void main()
{
char *name;
printf("
Enter the file name...:");
scanf("%s",name);


playwav(name,1.0);

}


void playwav(char wavefile[14],float delaytime);
struct WaveData {
unsigned int SoundLength, Frequency;
char *Sample;
};


struct HeaderType {
long RIFF; //RIFF header
char NI1 [18]; //not important

unsigned int Channels; //channels 1 = mono; 2 = stereo
long Frequency; //sample frequency
char NI2 [6]; //not important
char BitRes; //bit resolution 8/16 bit
char NI3 [12]; //not important
} Header;





struct WaveData Voice; //Pointer to wave file


unsigned int Base; //Sound Blaster base address


char WaveFile [25]; //File name for the wave file to be
played


/ Checks to see if a Sound Blaster exists at a given address, returns
true if Sound Blaster found, false if not.
/
int ResetDSP(unsigned int Test)
{
//Reset the DSP
outportb (Test + 0x6, 1);
delay(10);
outportb (Test + 0x6, 0);
delay(10);
//Check if (reset was succesfull
if ((inportb(Test + 0xE) & 0x80 == 0x80) && (inportb(Test + 0xA) ==
0xAA))
{
//DSP was found
Base = Test;
return (1);
}
else
//No DSP was found
return (0);
}


/ Send a byte to the DSP (Digital Signal Processor) on the Sound
Blaster
/
void WriteDSP(unsigned char Value)
{
//Wait for the DSP to be ready to accept data
while ((inportb(Base + 0xC) & 0x80) == 0x80);
//Send byte

outportb (Base + 0xC, Value);
}


/ Plays a part of the memory/

void PlayBack (struct WaveData *Wave)
{
long LinearAddress;
unsigned int Page, OffSet;
unsigned char TimeConstant;


TimeConstant = (65536 - (256000000 / Wave->Frequency)) >> 8;
WriteDSP(0x40); //DSP-command 40h - Set sample
frequency
WriteDSP(TimeConstant); //Write time constant


//Convert pointer to linear address
LinearAddress = FP_SEG (Wave->Sample);
LinearAddress = (LinearAddress << 4) + FP_OFF (Wave->Sample);
Page = LinearAddress >> 16; //Calculate page
OffSet = LinearAddress & 0xFFFF; //Calculate offset in the page
/*
Note - this procedure only works with DMA channel 1
*/
outportb (0x0A, 5); //Mask DMA channel 1
outportb (0x0C, 0); //Clear byte pointer
outportb (0x0B, 0x49); //Set mode
/*
The mode consists of the following:
0x49 = binary 01 00 10 01
| | | |
| | | +- DMA channel 01
| | +---- Read operation (the DSP reads from
memory)
| +------- Single cycle mode
+---------- Block mode
*/


outportb (0x02, OffSet & 0x100); //Write the offset to the DMA
controller
outportb (0x02, OffSet >> 8);


outportb (0x83, Page); //Write the page to the DMA
controller


outportb (0x03, Wave->SoundLength & 0x100);
outportb (0x03, Wave->SoundLength >> 8);


outportb (0x0A, 1); //Unmask DMA channel



WriteDSP(0x14); // DSP-command 14h - Single cycle
playback
WriteDSP(Wave->SoundLength & 0xFF);
WriteDSP(Wave->SoundLength >> 8);
}


/ Loads a wave file into memory.
This procedure expects a _very_ standard wave header.
It doesn't perform much error checking.
/
int LoadVoice (struct WaveData *Voice, char *FileName)
{
FILE *WAVFile;


//If it can't be opened...
WAVFile = fopen(FileName, "rb");
if (WAVFile == NULL) {
//..display error message


return (0);
}


//Return length of file for sound length minus 48 bytes for .WAV
header
fseek(WAVFile, 0L, SEEK_END);
Voice->SoundLength = ftell (WAVFile) - 48;
fseek(WAVFile, 0L, SEEK_SET);


//Check RIFF header
if (Voice->SoundLength > 32000) {




if (Voice->SoundLength > 64000) {


Voice->SoundLength = 64000;
}
}
free(Voice->Sample);
Voice->Sample = (char *)malloc(Voice->SoundLength); //Assign memory
if (!Voice->Sample) {

return (0);
}


//Load the sample data
fread(&Header, 46, 1, WAVFile);


//Check RIFF header
if (Header.RIFF != 0x46464952) {
printf ("Not a wave file
");
return (0);
}


//Check channels
if (Header.Channels != 1) {
printf ("Not a mono wave file
");
return (0);
}


//Check bit resolution
if (Header.BitRes != 8) {
printf ("Not an 8-bit wave file
");
return (0);
}


Voice->Frequency = Header.Frequency;


//Load the sample data
fread(Voice->Sample, Voice->SoundLength + 2, 1, WAVFile);


fclose (WAVFile); //Close the file


return (1);
}


void playwav (char wavefile[14], float delaytime )
{
delaytime=1.0;
if (ResetDSP (0x220)) {
//at 220h
printf ("");
} else {
if (ResetDSP (0x240)) {

//at 240h
printf ("");
} else {
//or none at all
printf ("");
return;
}
}




//Load wave file
if (LoadVoice (&Voice, wavefile)) {


//Start playback
PlayBack (&Voice);


delay(delaytime*1000);


//Stops DMA-transfer
WriteDSP (0xD0);
}
}


Simple solutions for complex problems on single linked list..

Listed here are few common complex operations of single linked list that is to be needed by certain applications. These operations should be done in single traversal for improved performance.

Here are few of them and their solutions..

1. Reverse the list.
2. Find n-th node from tail end.
3. Find middle node of the list.
4. Delete a node whose address is known, without having the head node's address.

1. Reverse the list
Logic :

    a. Get each node from front end till last.
    b. Add them into another list at front.

2. Find n-th node from tail end.

    a. Have two pointers pointer1 and pointer2.
    b. Point all of them to head initilally.
    c. Move only pointer1 for n nodes.
    d. Move both pointers for the rest nodes of list.
    e. At the end of traversal, pointer2 will be pointing to n-th node from tail.

3. Find middle node of the list.

    a. Have two pointers pointer1 and pointer2.
    b. Point all of them to head initilally.
    c. Move only pointer1 by one node.
    d. Move pointer2 by two nodes till the end of list.
    e. At the end of traversal, pointer1 will be pointing to middle node from tail.

4. Delete a node without having the head node's address

    a. copy the contents of next node's data to current node's data.
    b.Store the next node's next node at current node's link.

In all cases, we have to take care of boundary conditions as well as memory leaks.
Here is the code..

Code: C

#include

struct node
{
    int data;
    struct node* next;
};

// Functions for allocating/deallocating memory
struct node* create_node(int data);

// Utility functions that can be used in reverse_list
struct node* insert_at_front(struct node* head, struct node* new_node);
struct node* insert_at_end(struct node* head, struct node* new_node);

struct node* remove_from_front(struct node* head);
struct node* reverse_list(struct node* head);

// Delete a node without having the head pointer..
void delete_this_node(struct node* cur_node);

// Find nth node from tail in single traversal..
struct node* find_nth_from_end(struct node* head, int n);

// Find middle node of the list in single traversal..
struct node* find_middle_node(struct node* head);

// Dump the list/node..
void dump_list(struct node* head);
void dump_node(struct node* pNode);
void copy_node(struct node* src, struct node* dest);

// Main function
int main(void)
{
    struct node *list = NULL, *temp_node = NULL;
    int i = 0;

// Create list with 10 members...
    for(i = 0; i <= 10; i++) {
        temp_node = create_node(i);
        list = insert_at_end(list, temp_node);
    }

// Add 5 more in front...
    for(i = 14; i >= 11; i--) {
        temp_node = create_node(i);
        list = insert_at_front(list, temp_node);
    }

    dump_list(list);

// To reverse a single linked list in single traversal.......
/*
    list = reverse_list(list);
*/

// Delete a particular node without having the head pointer
/*
    temp_node = list;

    for(i = 0; i <= 15; i++) {

        if(i == 4) {
            delete_this_node(temp_node);
            break;
        }

        temp_node = temp_node->next;
    }
    dump_list(list);
*/

// To find nth node from the end of list in single traversal....
/*
    temp_node = find_nth_from_end(list, 10);

    dump_node(temp_node);
*/

// To find the middle node of list in single traversal......

/*
    temp_node = find_middle_node(list);

    dump_node(temp_node);

    list = reverse_list(list);

    dump_list(list);

    temp_node = find_middle_node(list);

    dump_node(temp_node);
*/
    return 0;
}

// Allocate memory and store the data
struct node* create_node(int data)
{
    struct node *new_node = NULL;

    new_node = (struct node*)malloc(sizeof(struct node));

    new_node->data = data;
    new_node->next = NULL;

    return new_node;
}

// Deallocate the memory
void free_this_node(struct node* pNode)
{
    free(pNode);
    pNode = NULL;

    return;
}

// Insert a node at front end
struct node* insert_at_front(struct node* head, struct node* new_node)
{
    if(new_node) {
        new_node->next = head;
        return new_node;
    }
    else
        return NULL;
}

// Insert a node at tail end
struct node* insert_at_end(struct node* head, struct node* new_node)
{
    struct node *temp = NULL;

    if(head) {

        temp = head;

        while(temp->next)
            temp = temp->next;

        temp->next = new_node;
    }
    else {
        head = new_node;
    }

    return head;
}

// Remove a node from front end..
struct node* remove_from_front(struct node* head)
{
    if(head) {
        head = head->next;
        return head;
    }
    else
        return NULL;
}

// Reverse the list in single traversal..
struct node* reverse_list(struct node* head)
{
    struct node *result = NULL, *temp_head = NULL, *temp = NULL;

    temp_head = head;

    while(temp_head) {

        temp = temp_head;

        temp_head = remove_from_front(temp_head);

        temp->next = NULL;

        result = insert_at_front(result, temp);
    }

    return result;
}

// Delete a node without the help of head node..
void delete_this_node(struct node* cur_node)
{
    struct node *temp = NULL;
    if(cur_node && cur_node->next) {

        copy_node(cur_node, cur_node->next);
        temp = cur_node->next;
        cur_node->next = cur_node->next->next;

        free_this_node(temp);
    }
    else if(cur_node) {
        free_this_node(cur_node);
    }
    else
        return;
}

// Find n-th node from tail end in single traversal...
struct node* find_nth_from_end(struct node *head, int n)
{
    struct node *temp = NULL, *result = NULL, *temp_head = NULL;
    int i = 0;

    result = temp_head = temp = head;

    for(i = 0; i < n; i++) {
        if(!temp_head) {
            printf("Out of Range\n");
            return NULL;
        }
        temp_head = temp_head->next;
        temp = temp->next;
    }

    while(temp_head) {
        temp_head = temp_head->next;
        temp = temp->next;
        result = result->next;
    }

    return result;
}

// Find middle node of list in single traversal...
struct node* find_middle_node(struct node* head)
{
    struct node *temp_head = NULL, *temp = NULL, *result = NULL;

    temp_head = temp = result = head;

    while(temp && temp->next) {

        if(temp->next->next) {
            temp = temp->next->next;
            result = result->next;
        }
        else
            temp = temp->next;
    }

    return result;
}

// Dump the list...
void dump_list(struct node* head)
{
    struct node *temp = NULL;

    printf("\n");

    if(head) {

        temp = head;

        while(temp) {
            printf("%d ", temp->data);
            temp = temp->next;
        }
    }
    else {
        printf("Empty List");
    }

    printf("\n");
}

// Copy data in b/w two nodes...
void copy_node(struct node* src, struct node* dest)
{
    src->data = dest->data;

    return;
}

// Dump a node
void dump_node(struct node* pNode)
{
    if(pNode)
        printf("\nNode details : Addr : %x, data : %d\n", pNode, pNode->data);
    else
        printf("\n Node is NULL \n");

    return;
}

Memory Leak detection Program without using any tools

This program is tested on Sun-Solaris system using gcc compiler.

In market, there are a lot of tools for detecting the memory leaks. Here I made a program which has to include in your source file and it will tell the desired informations to find where memory leaks happen.

There are two files one is findLeak.c and other is findLeak.h . Source file is test.c , this is your program which you want to check memory leaks.

Concept is that when user call library function "malloc or calloc " for allocating dynamic memory, then we have to call our malloc or calloc (In case of my source code 'MyCalloc' function in place of 'calloc' and MyMalloc function in place of 'malloc'). So we have to define malloc to your malloc and in .c file you have to undef malloc and calloc By this way we can call our MyMalloc or MyCalloc function and in this function we will call another function which keeps all info about how much memory allocated. We will do the same for Library function "free" to deallocating memory( In my source file "MyFree" is used in plae of free function).

Now for keeping information, i made a simple singly linked list. which will add info about memory when user call "malloc" or "calloc" function and will also keep information when user call "free" function.

By program you can easily understand.


Heder File : findLeak.h
#define   uint                 unsigned int 
#define   cchar                const char                     
#define   OutFile             "/home/asadulla/test/MemLeakInfo.txt"   // Just Suppose
#define  MAX_FILENAME_LENGTH   256
#define  calloc(objs, nSize)          MyCalloc (objs, nSize, __FILE__, __LINE__)
#define  malloc(nSize)                MyMalloc (nSize, __FILE__, __LINE__)
#define  free(rMem)                   MyFree(rMem)
 
// This structure is keeping info about memory leak
 
struct InfoMem
{
      //starting address of memory where pointer points 
    void *addr; 
      //Total size of memory in bytes which By malloc 
      //allocates  memory dynamically */
    uint nSize; 
      //Source File Name which you want
      //to  find memory leak information 
    char fileName[MAX_FILENAME_LENGTH]; 
        //Line number of source File due to                                                                             
       // which User forget to deallocate   memory 
    uint lineNumber; 
};
typedef struct InfoMem infoMem;
 
//This is link list of InfoMem which keeps a List of memory Leak in a source file
 
struct LeakMem
{
    infoMem memData;     
    struct LeakMem *nxt;   // Next Memory leak Block
};
typedef struct LeakMem leakMem;
 
// This function is used for writing into file to see the memory leaks summary
void WriteMemLeak(void);
 
// These two function add information of memory leak information when user 
// calls malloc or calloc
void SubAddMemInfo(void *rMem, uint nSize,  cchar  *file, uint lno);
void SubAdd(infoMem alloc_info);
 
// These two function remove and deallocated  memory and remove the leak 
//  information when user calls free function
void ResetInfo(uint pos); //erase
void DeleteAll(void); //clear(void);
 
// This is hidden to user , This function will call when user call malloc function
void *MyMalloc(uint size, cchar *file, uint line);
// This is hidden to user , This function will call when user call calloc function
void *MyCalloc(uint elements, uint size, cchar * file, uint lno);
// This is hidden to user , This function will call when user call free function
void  MyFree(void * mem_ref);


Source File: findLeak.c
#include    h>
#include    h>
#include    h>
#include    "findLeak.h"
 
#undef    malloc
#undef    calloc
#undef   free
 
 
static leakMem * ptr_start = NULL;
static leakMem * ptr_next =  NULL;
 
 
 
 
// -----------------------------------------------------------
// Name: MyMalloc
// Desc: This is hidden to user. when user call malloc function then 
//       this function will be called.
 
 
void *MyMalloc (uint nSize, cchar* file, uint lineNumber)
{
    void * ptr = malloc (nSize);
    if (ptr != NULL) 
    {
        SubAddMemInfo(ptr, nSize, file, lineNumber);
    }
    return ptr;
}
 
// -----------------------------------------------------------
// Name: MyCalloc
// Desc: This is hidden to user. when user call calloc function then 
//       this function will be called.
 
 
void * MyCalloc (uint elements, uint nSize, const char * file, uint lineNumber)
{
    uint tSize;
    void * ptr = calloc(elements , nSize);
    if(ptr != NULL)
    {
        tSize = elements * nSize;
        SubAddMemInfo (ptr, tSize, file, lineNumber);
    }
    return ptr;
}
 
// -----------------------------------------------------------
// Name: SubAdd
// Desc: It's actually  Adding the Info.
 
 
void SubAdd(infoMem alloc_info)
{
    leakMem * mem_leak_info = NULL;
    mem_leak_info = (leakMem *) malloc (sizeof(leakMem));
    mem_leak_info->memData.addr = alloc_info.addr;
    mem_leak_info->memData.nSize = alloc_info.nSize;
    strcpy(mem_leak_info->memData.fileName, alloc_info.fileName); 
    mem_leak_info->memData.lineNumber = alloc_info.lineNumber;
    mem_leak_info->nxt = NULL;
 
    if (ptr_start == NULL)  
    {
        ptr_start = mem_leak_info;
        ptr_next = ptr_start;
    }
    else {
        ptr_next->nxt = mem_leak_info;
        ptr_next = ptr_next->nxt;            
    }
 
}
 
 
 
// -----------------------------------------------------------
// Name: ResetInfo
// Desc: It erasing the memory using by List on the basis of info( pos)
 
 
void ResetInfo(uint pos)
{
 
    uint index = 0;
    leakMem * alloc_info, * temp;
    
    if(pos == 0)
    {
        leakMem * temp = ptr_start;
        ptr_start = ptr_start->nxt;
        free(temp);
    }
    else 
    {
        for(index = 0, alloc_info = ptr_start; index < pos; 
            alloc_info = alloc_info->nxt, ++index)
        {
            if(pos == index + 1)
            {
                temp = alloc_info->nxt;
                alloc_info->nxt =  temp->nxt;
                free(temp);
                break;
            }
        }
    }
}
 
// -----------------------------------------------------------
// Name: DeleteAll
// Desc: It deletes the all elements which resides on List
 
void DeleteAll()
{
    leakMem * temp = ptr_start;
    leakMem * alloc_info = ptr_start;
 
    while(alloc_info != NULL) 
    {
        alloc_info = alloc_info->nxt;
        free(temp);
        temp = alloc_info;
    }
}
 
 
// -----------------------------------------------------------
// Name: MyFree
// Desc: 
 
 
void MyFree(void * mem_ref)
{
        uint loop;
   // if the allocated memory info is part of the list, removes it
    leakMem  *leak_info = ptr_start;
    /* check if allocate memory is in our list */
    for(loop = 0; leak_info != NULL; ++loop, leak_info = leak_info->nxt)
    {
        if ( leak_info->memData.addr == mem_ref )
        {
            ResetInfo(loop);
            break;
        }
    }
    free(mem_ref);
}
 
 
// -----------------------------------------------------------
// Name: SubAddMemInfo
// Desc: it also fill the the Info
 
 
void SubAddMemInfo (void * mem_ref, uint nSize, cchar * file, uint lineNumber)
{
    infoMem AllocInfo;
 
    /* fill up the structure with all info */
    memset( &AllocInfo, 0, sizeof ( AllocInfo ) );
    AllocInfo.addr  = mem_ref;
    AllocInfo.nSize = nSize;
    strncpy(AllocInfo.fileName, file, MAX_FILENAME_LENGTH);
    AllocInfo.lineNumber = lineNumber;
    
    /* SubAdd the above info to a list */
    SubAdd(AllocInfo);
}
 
// -----------------------------------------------------------
// Name: WriteMemLeak
// Desc: It writes information about Memory leaks in a file 
//       Example: File is as : "/home/asadulla/test/MemLeakInfo.txt"
 
 
 
void WriteMemLeak(void)
{
    uint index;
    leakMem *leak_info;
 
    FILE * fp_write = fopen(OutFile, "wt");
    char info[1024];
 
    if(fp_write != NULL)
    {
        sprintf(info, "%s\n", "SUMMARY ABOUT MEMORY LEAKS OF YOUR SOURCE FILE ");
        fwrite(info, (strlen(info) + 1) , 1, fp_write);
        sprintf(info, "%s\n", "-----------------------------------");   
        fwrite(info, (strlen(info) + 1) , 1, fp_write);
        
        for(leak_info = ptr_start; leak_info != NULL; leak_info = leak_info->nxt)
        {
 
            sprintf(info, "Name of your Source File                 : %s\n", leak_info->memData.fileName);
            fwrite(info, (strlen(info) + 1) , 1, fp_write);
 
            sprintf(info, "Starting Address                         : %d\n", leak_info->memData.addr);
            fwrite(info, (strlen(info) + 1) , 1, fp_write);
 
            sprintf(info, " Total size Of memory Leak               : %d bytes\n", leak_info->memData.nSize);         
            fwrite(info, (strlen(info) + 1) , 1, fp_write);
 
            sprintf(info, "Line Number for which no DeAllocation    : %d\n", leak_info->memData.lineNumber);
            fwrite(info, (strlen(info) + 1) , 1, fp_write);
 
            sprintf(info, "%s\n", "-----------------------------------");   
            fwrite(info, (strlen(info) + 1) , 1, fp_write);
      fwrite(info, (strlen(info) + 1) , 1, fp_write);
        }
    }   
    DeleteAll();
}



Source File : test.c
#includeh>
#include"findLeak.h"
 
int main()
{
    int *p1 = (int *)malloc(10)
    int *p2 = (int *)calloc(10, sizeof(int));
    char *p3 = (char *) calloc(15, sizeof(float));
    float *p4 = (float*) malloc(16);
    free(p2);
    WriteMemLeak();
    return 0;
 }

Now user can compile these programmes in a console as :
> g++ test.c findLeak.c
and give a command for run
> ./a.out

then go to you your directory where you have defined a macro "OutFile" and open this defined file and you can see the results.

Output of above source file is as:
Code: output
SUMMARY ABOUT MEMORY LEAKS OF YOUR SOURCE FILE 
 
-----------------------------------
 
Name of your Source File                 : test.c
 
Starting Address                         : 184960
 
 Total size Of memory Leak               : 10 bytes
 
Line Number for which no DeAllocation    : 7
 
-----------------------------------
 
-----------------------------------
 
Name of your Source File                 : test.c
 
Starting Address                         : 187104
 
 Total size Of memory Leak               : 60 bytes
 
Line Number for which no DeAllocation    : 9
 
-----------------------------------
 
-----------------------------------
 
Name of your Source File                 : test.c
 
Starting Address                         : 184984
 
 Total size Of memory Leak               : 16 bytes
 
Line Number for which no DeAllocation    : 10
 
-----------------------------------
 
-----------------------------------