Elementolab/C Language Tips

From Icbwiki

Jump to: navigation, search

Contents

C++ project management

Useful tutorials:

  • Using Automake and Autoconf with C++ link
  • Autotools: a practitioner's guide to Autoconf, Automake and Libtool link
  • Tips using Autotools link
  • Using conditionals link

Libraries

  • Eigen value decomposition in C using GSL
http://www.gnu.org/software/gsl/manual/html_node/Eigenvalue-and-Eigenvector-Examples.html
cc -o test_eigen test_eigen.c -lgsl -lgslcblas

Debugging

  • A suite of tools for debugging and profiling
http://valgrind.org/
User Manual

With valgrind-massif tool you can check how much memory your program needs. Here's an example:

valgrind --tool=massif --massif-out-file=/tmp/chipseeqer.0.massif ./ChIPseeqer.bin -chipdir /chip -inputdir /input  \
-outfile /test.txt -chrdata /ChIPseeqer/data/hg18.chrdata -format eland 

That's not all, you need to print the results:

 ms_print /tmp/chipseeqer.0.massif

The valgrind-memcheck tool can detect:

1.off-by-one-errors

2.memory leaks

3.open file descriptors

4.uninitialized variables

Here's an example:

valgrind --tool=memcheck --trace-children=yes --log-file=/tmp/chipseeqer.0.valgrind --dsymutil=yes --track-fds=yes \
--leak-check=full --show-reachable=yes ./ChIPseeqer.bin -chipdir /chip -inputdir /input  -outfile /test.txt \
-chrdata /ChIPseeqer/data/hg18.chrdata -format eland

If errors and memory leaks are detected for your program, you will see something like this in the log file:

==19883== LEAK SUMMARY:
==19883==    definitely lost: 15,575 bytes in 2,665 blocks
==19883==    indirectly lost: 138 bytes in 25 blocks
==19883==      possibly lost: 0 bytes in 0 blocks
==19883==    still reachable: 8,680 bytes in 11 blocks
==19883==         suppressed: 0 bytes in 0 blocks
==19883== 
==19883== For counts of detected and suppressed errors, rerun with: -v
==19883== ERROR SUMMARY: 774 errors from 12 contexts (suppressed: 0 from 0)
  • Command line option processing
http://www.ibm.com/developerworks/aix/library/au-unix-getopt.html

Memory

  • C/C++ Memory Corruption And Memory Leaks
Basically, 
* The strdup() function internally calls malloc() and you MUST use free() ! 
* Avoid strsep() and strtok() !
Read more at http://www.yolinux.com/TUTORIALS/C++MemoryCorruptionAndMemoryLeaks.html

STL

  • C++ vectors usage
http://en.wikipedia.org/wiki/Vector_%28C%2B%2B%29


Documenting your code

  1. By default \todo does not sort your TO DO list by priority. To set items of different levels of priority, edit your docs.cfg, find the line corresponding to ALIASES and add:
ALIASES += "todo1=\xrefitem todo1 \"High Priority Todo\" \"Todo high priority list\""
ALIASES += "todo2=\xrefitem todo2 \"Medium Priority Todo\" \"Todo medium priority list\""
ALIASES += "todo3=\xrefitem todo3 \"Low Priority Todo\" \"Todo low priority list\""

http://skramm.blogspot.com/2010/02/enhancement-to-todo-command-with.html
  • Beautify your C/C++/C#/Java source code:

Try the Artistic Style formatter. Download at http://astyle.sourceforge.net/

Example usage:
./astyle --indent=tab my_code.cpp
  • Pretty-print your source code:
enscript -q -B -C -Esh -G --color --word-wrap -f Courier7 -MA4 -T4 -p - test.cpp | pstopdf -i -o test.pdf

Timing

http://beige.ucs.indiana.edu/B673/node104.html

Misc.

  • Line Iterator (uses BIO-C; ~50% faster than fgets())
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dataio.h"

int main(int argc, char** argv) {

 LineI li;
 char* l;

 li.bufflen = 1000000;
 LineIopen(&li, argv[1]);
 while (l = nextLine(&li)) {
   printf("%s\n", l);
   free(l);
 }
 LineIclose(&li);
 return 0;
}


  • Hash table (using Olivier's BIO-C code)
 #include <search.h>
 #include "hashtable.h"
 #define MAXNUMENTRIES 10000
 
 /* hash table variables */
 int    hashret;
 ENTRY  e;
 ENTRY* ep;
 struct my_hsearch_data* hash_genes;
 
 /* build a hash table */
 hash_genes = (struct my_hsearch_data*)calloc(1,  sizeof(struct my_hsearch_data));
 hashret = my_hcreate_r(MAXNUMENTRIES, hash_genes);
 if (hashret == 0) {
   printf("Could not create hash table ...\n");
   exit(0);
 }
 
 /* enter key/value pair into hash */
 e.key   = strdup( genename );
 e.data  = (char*)idx;
 hashret = my_hsearch_r(e, ENTER, &ep, hash_genes);
 if (hashret == 0) {
   printf("Could not enter entry into hash table ...\n");
   exit(0);
 }
  
 /* query */
 e.key = mygene;        
 my_hsearch_r(e, FIND, &ep, hash_genes) ;  
 if (ep) {
    /* success */
    int idx = (int)(ep->data);
 }
  • C equivalent of
 # Perl
 open IN, $ARGV[0];
 while (my $l = <IN>) {
   chomp $l;
   my @a = split /\t/, $l, -1;
 }
 close IN;


 # C (uses some BIO-C functions too)
 char*  buff;
 int    mynmax = 100000;
 char** a;
 int    m;
 FILE*  f1     = 0;
 buff  = (char*)malloc(mynmax * sizeof(char));  
 f1 = fopen(argv[1], "r");
 if (!f1) {
   die("Cannot open f1\n");
 }
 num = 0;
 while (!feof(f1)) {
   fgets(buff, mynmax, f1);
   if (feof(f1))
     break; 
   chomp(buff);
   split_line_delim(buff, " ", &a, &m);
   free(a)
 }
 fclose(f1);
 free(buff);
Personal tools