I have been currently working on an implementation in C++. I am new in C++ and want to be better. In initial step of the task, I need to read a file and store some part of the data in a dynamic array whose type is a class, "Sequence", as following;
class Sequence{
private:
char *seq;
int length;
public:
/* Setter and getter declarations */
void setSeq(char *);
char *getSeq();
void setLength(int);
int getLength();
/* Constructors and destructor */
Sequence();
Sequence(std::string);
Sequence(std::string, unsigned);
~Sequence();
/* Overloaded = operator */
void operator = (Sequence *sequence)
{
seq = sequence->seq;
length = sequence->length;
};
};
/* Constructor definitions */
Sequence::Sequence(){/* Default Constructor*/}
Sequence::Sequence(std::string str)
{
seq = &str[0u];
length = str.length();
}
Sequence::Sequence(std::string str, unsigned count)
{
seq = &str[0u];
length = count;
}
/* Destructor definition */
Sequence::~Sequence(){/* Default Destructor */}
/* Setter and getter definitions */
void Sequence::setSeq(char *seq){
this->seq = seq;}
char * Sequence::getSeq(){
return seq; }
void Sequence::setLength(int length){
this->length = length; }
int Sequence::getLength(){
return length; }
/* Forward declaration of file reading functions */
unsigned getCountOfSequences(char *);
Sequence *getSequences(char *, unsigned);
The following is the cpp file;
#include <fstream>
#include "file_operations.h"
unsigned getCountOfSequences(char *fileName)
{
std::ifstream file(fileName);
std::string str;
unsigned count;
/* Get total number of sequences*/
file.unsetf(std::ios_base::skipws);
count = std::count(
std::istream_iterator<char>(file),
std::istream_iterator<char>(), '\n')/4;
file.close();
return count;
}
/*
* Function : read_sequences
* Goal : reading the file in FASTQ format to
* get all the sequences into a set in Sequence type
* Input : name of the file
* Output : a set of sequences in Sequence type
*/
Sequence *getSequences(char *fileName, unsigned count)
{
/* Used variables while reading file */
std::ifstream file(fileName);
std::string str;
/*Define a set of sequence dynamically*/
Sequence *setOfSeqs = new Sequence[count];
/* Put total number of seqs into first seq */
setOfSeqs[0] = new Sequence("COUNT", count);
/* Read each sequence and put it into set */
int lineIndex = 1; int seqIndex = 0;
while (getline(file, str))
{
/* This is the line of sequence */
if ( lineIndex == 2 )
{
/* Define a temporary sequence */
Sequence *newSeq = new Sequence(str);
/* Add new seq to set of sequences */
setOfSeqs[++seqIndex] = new Sequence(str);
/* --- PART A --- */
//delete newSeq;
std::cout << setOfSeqs[seqIndex].getSeq() << "\n";
}
/* Loop updates */
lineIndex = (lineIndex == 4) ? 0 : lineIndex;
lineIndex ++;
}
file.close();
/* --- PART B --- */
for ( int i = seqIndex; i > 0; i -- )
{
std::cout << setOfSeqs[i].getSeq() << "\n";
}*/
return setOfSeqs;
} // read_sequences() function
Now, I have two main questions to understand the pointers and dynamic memory allocation in C++. As you got, I just want to read the file, put the data in an array(dynamically defined in "Sequence" type) and return it to a different .cpp file to be used.
My first question is about the data is changed after the loop ended. There are two parts are commented out as "PART A" and "PART B" to focus on. All the data I read in the "PART A" is correctly printed out line by line. However, if I try to print those lines(stored in setOfSeqs) in the "PART B", I encountered different data, which was incorrect, especially there were multiples of the same data mostly. Now, why I lost the data(or the data was diferent) I read in the while loop?
My second question is about the deallocation of memory in C++. As you see, in the while loop, I created a "Sequence" object and add it into array, setOfSeqs, after constructed it. Now, if I uncommented the line, delete newSeq;, in "PART B", after I copied the object(newSeq) into one of the setOfSeqs elements, why I got an empty string when I tried to printed setOfSeqs element in the next line? Indeed, I just deleted the newly created object, not the setOfSeqs element. From my perspective, I equalized the object to the element, so the data in the setOfSeqs element should not be lost.
In addition, even though, I was able to print the correct data in "PART B" (before returning the setOfSeqs) once, result of the print statement in the other .cpp file was again empty?
Thank you all in advance.