Thread: debugging

  1. #1
    Registered User Ssfccsh's Avatar
    Join Date
    Sep 2003
    Posts
    11

    Unhappy debugging

    Need help. I have spent a lot of time debugging this: (finally i gave up ).Thanks for all those who tool the time to read my codes.

    note:code in red denotes place of problem encountered.

    /*Gene expression data is obtained by experiments and it records the
    expression levels of genes under specific experimental conditions.
    Two types of experiments is considered in this case.The first type (temporal)
    is aimed at simultaneously monitoring the n genes m times under a series of
    varying conditions.The second type (spacial) is used to examine the n genes
    in a single environment but from m different cells.*/
    Dun ask what

  2. #2
    Registered User Ssfccsh's Avatar
    Join Date
    Sep 2003
    Posts
    11

    here's the code (part1)

    Code:
    #include <iostream>
    #include <iomanip>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    /***************************************************/
    /*                                CLASSES                                                    */
    /***************************************************/
    
    /***************************************************/
    /*                                class gene                                                 */
    /***************************************************/
    class gene
    {
     public:
      gene(){name = ""; identifier = 0;};
      void setgene(string genename, int geneidentifier)
        {name = genename; identifier = geneidentifier;};
      string getgenename(){return name;};
      int getgeneidentifier(){return identifier;};
      void printgene(void){cout << "\t" << name << endl;};
      ~gene(){};
     private:
      string name;
      int identifier;
    };
    
    /***************************************************/
    /*                                class condition                                           */
    /***************************************************/
    class condition
    {
     public:
      condition(){name = ""; identifier = 0;};
      void setcondition(string conditionname, int conditionidentifier)
        {name = conditionname; identifier = conditionidentifier;};
      string getconditionname(){return name;};
      int getconditionidentifier(){return identifier;};
      void printcondition(void){cout << "\t" << name << endl;};
      ~condition(){};
     private:
      string name;
      int identifier;
    };
    
    /***************************************************/
    /*                                class cell                                                    */
    /***************************************************/
    class cell
    {
     public:
      cell(){name = ""; identifier = 0;};
      void setcell(string cellname, int cellidentifier)
        {name = cellname; identifier = cellidentifier;};
      string getstringname(){return name;};
      int getstringidentifier(){return identifier;};
      void printcell(void){cout << "\t" << name << endl;};
      ~cell(){};
     private:
      string name;
      int identifier;
    };
    
    /***************************************************/
    /*                                class gene expression                               */
    /***************************************************/
    class geneexp
    {
     public:
      geneexp(){temporal = 0; spacial = 0; row = 0; col = 0;};
      void setnumberofgenes(int);
      void setnumberofconditions(int);
      void setnumberofcells(int);
      void setgenes(string genename, int i)
        {genes[i].setgene(genename, i + 1);}; 
      void setconditions(string conditionname, int i)
        {conditions[i].setcondition(conditionname, i + 1);};
      void setcells(string cellname, int i)
        {cells[i].setcell(cellname, i + 1);};
      void settemporal(void){temporal = 1;};
      void setspacial(void){spacial = 1;};
      void setmatrix(double**);
      int getrow(void){return row;};
      int getcol(void){return col;};
      void removegene(int);
      void printmatrix(void);
      void printgenes(void);
      void printconditions(void);
      void printcells(void);
      ~geneexp(){};
     private:
      int temporal;
      int spacial;
      gene *genes;
      condition *conditions;
      cell *cells;
      int row;
      int col;
      double **element;
    };
    /***************************************************/
    /*                                END OF CLASSES                                       */
    /***************************************************/
    
    
    /***************************************************/
    /*                                   METHODS                                                */
    /***************************************************/
    
    /***************************************************/
    /*                    class gene expression methods                            */
    /***************************************************/
    
    
    void geneexp::setnumberofgenes(int temprows)/*temprows = 4 is passed*/
    {
      row = temprows;
      cout << "in setnumberofgenes, row = " << row << endl;/*4 printed*/
      genes = new gene[temprows];
      cout << "in setnumberofgenes, row = " << row << endl;/*0 is printed!!*/
    }
    
    
    void geneexp::setnumberofconditions(int tempcolumns)
    {
      col = tempcolumns;
      conditions = new condition[tempcolumns];
    }
    
    void geneexp::setnumberofcells(int tempcolumns)
    {
      col = tempcolumns;
      cells = new cell[tempcolumns];
    }
    
    void geneexp::setmatrix(double **tempmatrix)
    {
      int i, j;
    
      /*perform dynamic memory allocatin for element[][]*/
      element = new double *[row];
      for(i = 0; i < row; ++i)
        element[i] = new double[col];
    
      /*copy values from tempmatrix[][]*/
      for(i = 0; i < row; ++i)
        for(j = 0; j < col; ++j)
          element[i][j] = tempmatrix[i][j]; 
    }
    
    void geneexp::removegene(int geneidentifier)
    {
      int i;
    
      genes[geneidentifier].setgene("", 0);
      
      /*if experiment is temporal, remove values of conditions*/
      if(temporal == 1)
        {
          for(i = 0; i < col; i++)
    	conditions[i].setcondition("", 0);
        }
    
      /*if experiment is spacial, remove values of cells*/
      else if(spacial == 1)
        {
          for(i = 0; i < col; i++)
    	cells[i].setcell("", 0);
        }
    }
    
    void geneexp:: printgenes(void)
    {
      int i;
      
      for(i = 0; i < row; ++i)
        genes[i].printgene();
    }
    
    void geneexp:: printconditions(void)
    {
      int i; 
      
      for(i = 0; i < col; i++)
        conditions[i].printcondition();
    }
    
    void geneexp:: printcells(void)
    {
      int i;
      
      for(i = 0; i < col; i++)
        cells[i].printcell();
    }
    
    void geneexp:: printmatrix(void)
    {
      int i, j;
    
      for(i = 0; i < row; i++)
        {
          for(j = 0; j < col; j++)
    	{
    	  cout.setf(ios::left);
    	  cout.width(15);
    	  cout << "\t" << element[i][j];
    	}
          cout << endl;
        }
    }
    /***************************************************/
    /*                                 END OF METHODS                                     */
    /***************************************************/
    Last edited by Ssfccsh; 02-27-2004 at 10:21 PM.
    Dun ask what

  3. #3
    Registered User Ssfccsh's Avatar
    Join Date
    Sep 2003
    Posts
    11

    code (part2)

    Code:
    /****************************************************************************/
    /*                                FUNCTION PROTOTYPES                       */
    /****************************************************************************/
    void removegenes(void);
    int readfile(string, geneexp *);
    void unexpressedgenes(void){};
    void maliciousgenes(void){};
    void omatrix(void){};
    /****************************************************************************/
    /*                        END OF FUNCTION PROTOTYPES                        */
    /****************************************************************************/
    
    /****************************************************************************/
    /*                                 MAIN FUNCTION                            */
    /****************************************************************************/
    int main(void)
    {
      int choice;
    
      do
        {
          cout << "\nAvailable selections:\n";
          cout << "\t[1] Remove genes\n";
          cout << "\t[2] Unexpressed genes\n";
          cout << "\t[3] Malicious genes\n";
          cout << "\t[4] Omatrix\n";
          cout << "\t[5] Quit\n" << endl;
          cout << "Your selection: ";
          cin >> choice;
    
          switch(choice)
    	{
    	case 1:
    	  removegenes();
    	  break;
    	case 2:
    	  unexpressedgenes();
    	  break;
    	case 3:
    	  maliciousgenes();
    	  break;
    	case 4:
    	  omatrix();
    	  break;
    	case 5:
    	  cout << "Program exited" << endl;
    	  break;
    	default:
    	  cout << "Invalid selection." << endl;
    	}
        }while(choice != 5);
    
      return 0;
    }
    /****************************************************************************/
    /*                            END OF MAIN FUNCTION                          */
    /****************************************************************************/
    
    /****************************************************************************/
    /*                            FUNCTION DEFINITIONS                          */
    /****************************************************************************/
    
    /****************************************************************************/
    /*                             read from file function                      */
    /****************************************************************************/
    int readfile(string filename, geneexp *geneexps)
    {
      string str;
      int numberofmatrix, fileptrposition, i, j;
      int rows, columns;
      double **matrix;
    
      ifstream file(filename.c_str(), ios::in);
      
      /*determine number of matrix contain in file*/
      for(numberofmatrix = 0; !file.eof(); )
        {
          file >> str;
          if(str == "<gene-exp>")
    	++numberofmatrix;
        }
      
      file.clear();
      file.seekg(0);
    
      /*set size of gene expression array*/
      geneexps = new geneexp[numberofmatrix];
    
      /*read until end of file encountered*/
      for(;!file.eof(); )
        {
          file >> str;
          
          /*read between <genes> and </genes>*/
          if(str == "<genes>")
    	{
    	  fileptrposition = file.tellg();
    	  file >> str;
    	  
    	  /*determine number of genes*/ 
    	  for(rows = 0; str != "</genes>"; ++rows)
    	      file >> str;
    
    	  file.seekg(fileptrposition);
    	  file >> str;
    
    	  /*set size of gene array*/
    	  geneexps[numberofmatrix].setnumberofgenes(rows);
    	  
    	  /*copy gene name from file*/
    	  for(i = 0; str != "</genes>"; i++)
    	    {
    	      geneexps[numberofmatrix].setgenes(str, i);
    	      file >> str;
    	    }
    
    	  /*display genes read from file*/
    	  cout << "\nGenes read:\n";
    	  geneexps[numberofmatrix].printgenes();
    	}
    
          /*read between <conditions> and </conditions>*/
          if(str == "<conditions>")
    	{
    	  geneexps[numberofmatrix].settemporal(); 
    	  fileptrposition = file.tellg();
    	  file >> str;
    
    	  /*determine number of conditions*/
    	  for(columns = 0; str != "</conditions>"; ++columns)
    	    file >> str;
    
    	  file.seekg(fileptrposition);
    	  file >> str;
    
    	  /*set size of condition array*/
    	  geneexps[numberofmatrix].setnumberofconditions(columns);
    	  
    	  /*copy condition name from file*/
    	  for(i = 0; str != "</conditions>"; ++i)
    	    {
    	      geneexps[numberofmatrix].setconditions(str, i);
    	      file >> str;
    	    }
    
    	  /*display conditions read from file*/
    	  cout << "\nConditions read:\n";
    	  geneexps[numberofmatrix].printconditions();
    	}
    
          /*read between <cells> and </cells>*/
          if(str == "<cells>")
    	{
    	  geneexps[numberofmatrix].setspacial(); 
    	  fileptrposition = file.tellg();
    	  file >> str;
    
    	  /*determine number of cells*/
    	  for(columns = 0; str != "</cells>"; ++columns)
    	    file >> str;
    
    	  file.seekg(fileptrposition);
    	  file >> str;
    
    	  /*set size of cell array*/
    	  geneexps[numberofmatrix].setnumberofcells(columns);
    
    	  /*copy cell name from file*/
    	  for(i = 0; str != "</cells>"; ++i)
    	    {
    	      geneexps[numberofmatrix].setcells(str, i);
    	      file >> str;
    	    }
    
    	  /*display cells read from file*/
    	  cout << "\nCells read:\n";
    	  geneexps[numberofmatrix].printcells();
    	}
          /*read between <matrix> and </matrix>*/
          if(str == "<matrix>")
    	{
    	  /*perfrom dynamic memory allocation for matrix[][]*/
    	  matrix = new double*[rows];
    	  for(i = 0; i < rows; ++i)
    	    matrix[i] = new double[columns];
    	  
    	  /*copy elements of matrix from file*/
    	  for(i = 0; i < rows; ++i)
    	    for(j = 0; j < columns; ++j)
    	      file >> matrix[i][j];
    	  
    	  /*transfer elements copied to element[][] in class geneexps[]*/
    	  geneexps[numberofmatrix].setmatrix(matrix);
    	}
        }
      return numberofmatrix;
    }
    
    /****************************************************************************/
    /*                  remove last n rows of genes function                    */
    /****************************************************************************/
    void removegenes(void)
    {
      string filename;
      int numberofmatrix;
      int i, j, input1, input2;
      geneexp *geneexps;
      
      /*get filename from user*/
      cout << "\nEnter filename storing gene expression matrix: ";
      cin >> filename;
      
      ifstream file(filename.c_str(), ios::in);
      
      if(!file)
        {
          cout << "File cannot be opened." << endl;
          return;
        }
      else
        {
          numberofmatrix = readfile(filename, geneexps);
          
          /*display matrix(s) read from file*/
          cout << "\nMatrix(s) read from " << filename << ":" << endl;
          for(i = 0; i < numberofmatrix; i++)
    	{
    	  cout << "Matrix " << i + 1<< ":" << endl;
    	  geneexps[i].printmatrix();
    	  cout << endl;
    	}
        }  
      
      cout << "Enter set of matrix to remove genes: ";
      cin >> input1;
      
      /*check input from user*/
      if(input1 < 1 || input1 > i + 1)
        {
          cout << "Invalid input." << endl;
          return;
        }
      
      cout << "Enter number of last rows to be removed: ";
      cin >> input2;
      
      /*check input from user*/
      if(input2 < 0 || input2 > geneexps[input1 - 1].getrow())
        {
          cout << "Invalid input." << endl;
          return;
        }
      
      j = geneexps[input1 - 1].getrow();
      
      /*remove starts from last row*/
      for(i = input2; i > 0; i--, j--)
        {
          geneexps[input1 - 1].removegene(geneexps[input1 - 1].getrow());
          geneexps[input1 - 1].setnumberofgenes(j - 1);
        }
    }
    /****************************************************************************/
    /*                         END OF FUNCION DEFINITIONS                       */
    /****************************************************************************/
    Last edited by Ssfccsh; 02-27-2004 at 10:15 PM.
    Dun ask what

  4. #4
    Registered User Ssfccsh's Avatar
    Join Date
    Sep 2003
    Posts
    11

    here an example of the files to be read:

    first file (geneexp1.txt):
    Code:
    <gene-exp>
    	<genes>
    		RPN1
    		RPN2
    		RPT2
    		TBP34
    	</genes>
    	<conditions>
    		normal
    		20-drug
    		50-drug
    	</conditions>
    	<matrix>
    		0.4	0	0.8
    		1.3	1.0	0.1
    		0.1	0	0
    		0.6	1.56	0.2
    	</matrix>
    </gene-exp>
    second file (geneexp2.txt):
    Code:
    <gene-exp>
    	<genes>
    		BETA6
    		CDC47
    		CAP15
    		CAP17
    	</genes>
    	<cells>
    		kidney
    		liver
    		lung
    	</cells>
    	<matrix>
    		1.4	0	0.5
    		2.3	1.7	0.1
    		0.8	0	0
    		0.7	1.0	0.2
    	</matrix>
    </gene-exp>
    Dun ask what

  5. #5
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    So what's the problem? Compile errors?

    Next time only post what part of the code is giving you problems (or at least what you think is giving you problems). If you really have to post large amounts of code from more than one file then put it in a zip and attach it.

    Edit: Ok I reread your post and I see you said you put problems in red..Let me look.
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  6. #6
    Tha 1 Sick RAT
    Join Date
    Dec 2003
    Posts
    271
    Exactly what is you problem?? Reading this much code takes time but if you mention what the problem is it helps to isolate the portion of code that may be causing you troubles.
    A hundred Elephants can knock down the walls of a fortress... One diseased rat can kill everyone inside

  7. #7
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Code:
    
    void geneexp::setnumberofgenes(int temprows)/*temprows = 4 is passed*/
    {
      row = temprows;
      cout << "in setnumberofgenes, row = " << row << endl;/*4 printed*/
      genes = new gene[temprows];
      cout << "in setnumberofgenes, row = " << row << endl;/*0 is printed!!*/
    }
    
    This is generally called stack whacking, however in this case we can call it heap whacking.

    The row variable is being overwritten for some reason when it should not be. Typical causes are buffer overflows. However, where they occur can be very subtle and this problem can be extremely difficult to track down. The only user function called between the values changing unexpectedly is the gene() constructor. There is no problem in there so we have to look wider(lucky you posted all the code)!

    Code:
      /*set size of gene expression array*/
      geneexps = new geneexp[numberofmatrix];
    
    	...
    
    	  /*set size of gene array*/
    	  geneexps[numberofmatrix].setnumberofgenes(rows);
    I'm sure you see the problem with that. So what happens:

    1. You allocate memory for geneexps array.
    2. You use the memory after the end of that array.
    3. In this case this works until... (it could crash here, undefined).
    4. You allocate memory for the genes array.
    5. Guess where that memory is allocated!
    6. Now you have a geneexp object in the same place as one or more gene objects. Not a good thing!

    Anyone who has experienced this problem has sympathy for you. It can be maddening to say the least! A good debugging tip is to comment out the code between the value changes until you find the line that is causing the overwrite and go from there.

  8. #8
    Registered User Ssfccsh's Avatar
    Join Date
    Sep 2003
    Posts
    11
    I have never expected such quick replies. Thanks to all that replied.

    a thousand apologies because i am still a beginner for c++. I still need further explaination for point 6 that is raised.

    This is my understanding of dynamic memory allocation. A section of memory allocated for one would not be replaced by another unless it is freed.

    If i assumed that my understanding is wrong, then how do we ensure that an already allocated dynamic memory will not be replaced.
    Last edited by Ssfccsh; 02-28-2004 at 01:02 AM.
    Dun ask what

  9. #9
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    This is my understanding of dynamic memory allocation. A section of memory allocated for one would not be replaced by another unless it is freed.
    That's right. However, you are using memory that you have not allocated and that is what is getting over written.

    Consider numberofmatrix to equal 3.
    Code:
      geneexps = new geneexp[3];
    That means you get 3 geneexp objects in memory:

    Code:
    ----------|----------|----------|----------|----------|
       ge[0]      ge[1]      ge[2]      ge[3]     ge[4]  
    ________________________________ ==========================
         memory you allocated            non-allocated memory
    So you can use geneexps[0], geneexps[1] and geneexps[2]. However, you are using geneexps[3].
    Code:
    	  geneexps[3].setnumberofgenes(rows);
    As you can see from the graphic, geneexps[3] is in the non-allocated memory zone.

    Now when you allocate memory for the genes array, it uses that memory and you have a problem.
    Code:
    ----------|----------|----------|------|------|------|
        ge0         ge1       ge2      gn1    gn2    gn3
                                     ----------
                                       ge3
    Both objects end up sharing memory! The lesson of this story is that you must only use memory you have allocated. Therefore, if you allocate an array of 3 objects you can use 0 to 2. If you allocate an array of 50 objects you can use 0 to 49 and so on.

    If you use past the end of the array as you have done it is called a buffer overflow.

    I suspect you want something like this:
    Code:
      for(int geIndex=0;!file.eof() && geIndex < numberofmatrix;geIndex++)
    
          ...
    
          geneexps[geIndex].setnumberofgenes(rows);

  10. #10
    Registered User Ssfccsh's Avatar
    Join Date
    Sep 2003
    Posts
    11
    Oh thanks...i have finally understood ur point.
    I have edited the codes accordingly but now a new problem surfaced!!
    I'll try to check it myself first....
    Dun ask what

  11. #11
    Registered User Ssfccsh's Avatar
    Join Date
    Sep 2003
    Posts
    11

    Hehe... i have managed to find the problem.
    Everything is working fine now.
    Dun ask what

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dev-C++: Problems with Breakpoint Debugging
    By Thileepan_Bala in forum C Programming
    Replies: 1
    Last Post: 01-17-2008, 10:48 AM
  2. Problem in debugging in Eclipse
    By Bargi in forum Linux Programming
    Replies: 1
    Last Post: 08-21-2007, 09:53 AM
  3. Debugging Dev C++
    By tuurb046 in forum Tech Board
    Replies: 10
    Last Post: 08-16-2007, 12:51 PM
  4. Debugging book recommendation
    By dagans in forum Projects and Job Recruitment
    Replies: 1
    Last Post: 09-13-2005, 07:35 PM
  5. debugging directx apps
    By confuted in forum C++ Programming
    Replies: 1
    Last Post: 08-16-2003, 08:56 AM