首页 > 解决方案 > 使用 3 个输入而不是 2 个输入时收到 malloc 错误

问题描述

这里的代码应该包含 dna 字母链/字符串('ATG' + 'CTA' = 'ATGCTA'),并能够将它们组合起来,并从组合链中减去特定部分。当用户必须输入两股时,组合工作正常,但是当有三股时,组合似乎中途被切断。任何帮助表示赞赏! 在此处输入图像描述

dnasequence.h

#include <iostream>
#include <string>

#ifndef _DNASEQUENCE_
#define _DNASEQUENCE_
using namespace std;

// class DNASequence 
//
// A class that contains a sequence of nucleotides in the dna_sequence.
// The max_sequence represents the capacity of the dna_sequence.
// A dna_sequence is a c-string of characters that consist only of
// 'A', 'T', 'G', 'C' standing for the 4 nucleotides and ending in a '\0'
// character. Input into the DNASequence is case-insensitive meaning that
// lower or upper case is acceptable, but it should be converted to uppercase
// internally.
//
class DNASequence {
    public:
        DNASequence(); 
        // Assume that the strand is made up of 100 sequences.

        DNASequence(string nucleotides);
        // Assume that the sequence is initialized to the nucleotides string.

        DNASequence(const DNASequence& arg);
        // Copy constructor

        ~DNASequence();
        // Destructor

        DNASequence& operator = (const DNASequence& arg);
        // Assignment operator

        bool operator == (const DNASequence& arg);
        // Equals operator compares the given sequence with the invoking object.

        bool operator != (const DNASequence& arg);
        // Not equals operator compares the given sequence with the invoking object.

        friend DNASequence operator + (const DNASequence& arg1, const DNASequence& arg2);
        // Append the given sequence onto the end of a copy of the invoking object sequence.

        friend DNASequence operator - (const DNASequence& arg1, const DNASequence& arg2);
        // Remove the given sequence from a copy of the invoking object if it exists. Return
        // the modified sequence. If the given sequence is not found, return the
        // invoking sequence unaltered.

        //checks if string is valid
        bool isitvalid(string str);

        friend istream& operator >> (istream& ins, DNASequence& arg);
        // Implement the friend function to read in a nucleotide sequence made up
        // of only the following characters: adenine (A), thymine (T), guanine (G)
        // and cytosine (C). Assume case insensitive but convert to upper internally.

        friend ostream& operator << (ostream& out, const DNASequence& arg);
        // Implement the friend function to write out a nucleotide sequence. No blanks.

        int get_max_sequence() const { return max_sequence; };
        // Accessor for max_sequence.

        char* get_dna_sequence() const { return dna_sequence; };
        // Accessor for dna_sequence.

    private:
        char* dna_sequence; // Dynamic array of char
        int max_sequence; // Maximum number of nucleotides.
};

#endif

dnasequence.cpp

#include <iostream>
#include <string>
#include <cstring>
#include <cctype>
#include "dnasequence.h"

using namespace std;

// Assume that the strand is made up of 100 sequences.
DNASequence::DNASequence() 
{
    this->dna_sequence = new char(101); // 100 + null
    max_sequence = 0;
}

// Assume that the sequence is initialized to the nucleotides string.
DNASequence::DNASequence(string nucleotides) 
{
    int i;
    dna_sequence = new char(nucleotides.length()+1);
    for(i = 0; i < nucleotides.length(); i++)
    {
        dna_sequence[i] = nucleotides.at(i);
    }
    dna_sequence[i] = '\0'; // Changed
    max_sequence = nucleotides.length();
    //cout << max_sequence << endl;
}

// Copy constructor
DNASequence::DNASequence(const DNASequence& arg)
{
   this->max_sequence = arg.get_max_sequence();
   this->dna_sequence = new char(this->max_sequence+1);
   int i = 0;
   for (i = 0; i < this->max_sequence; i++)
       dna_sequence[i] = arg.dna_sequence[i];
   dna_sequence[i] = '\0';
}

// Destructor
DNASequence::~DNASequence()
{
    delete dna_sequence;
}

// Assignment operator
DNASequence& DNASequence::operator = (const DNASequence& arg)
{
   this->max_sequence = arg.get_max_sequence();
   dna_sequence = new char(this->max_sequence+1);
   int i = 0;
   for (i = 0; i < this->max_sequence; i++)
   {
       dna_sequence[i] = arg.dna_sequence[i];
   }
   dna_sequence[i] = '\0';
   return *this;
}

// Equals operator compares the given sequence with the invoking object.
bool DNASequence::operator == (const DNASequence& arg)
{
   int i = 0, j = 0;
   while (this->dna_sequence[i] !='\0' && arg.dna_sequence[j]!='\0')
   {
       if (this->dna_sequence[i] != arg.dna_sequence[j])
           return false;           
       i++;
       j++;
   }
   if (this->dna_sequence[i] == '\0' && arg.dna_sequence[j] == '\0')
       return true;
    return false;
}

bool DNASequence::operator != (const DNASequence& arg)
{
   int i = 0, j = 0;
   while (this->dna_sequence[i] != '\0' && arg.dna_sequence[j] != '\0')
   {
       if (this->dna_sequence[i] != arg.dna_sequence[j])
           return true;
       i++;
       j++;
   }
   if (this->dna_sequence[i] == '\0' && arg.dna_sequence[j] == '\0')
       return false;
   return true;
}


// Append the given sequence onto the end of the invoking object sequence.
DNASequence operator + (const DNASequence &arg1, const DNASequence &arg2)
{
   DNASequence temp = arg1;
   if (arg1.get_max_sequence() == 0)
       return arg2;
   if (arg2.get_max_sequence() == 0)
       return arg1;

   temp.max_sequence = arg1.get_max_sequence() + arg2.get_max_sequence();
   temp.dna_sequence = new char(temp.max_sequence + 1);
   //cout << temp.max_sequence;
   int i = 0;
   for (int j = 0; j < arg1.get_max_sequence(); j++)
   {
       temp.dna_sequence[i] = arg1.dna_sequence[j];
       i++;
       //cout << i << endl; debug line
   }
   //i++; // changed

   for (int j = 0; j < arg2.get_max_sequence(); j++)
   {
       temp.dna_sequence[i] = arg2.dna_sequence[j];
       i++;
       //cout << i << endl; debug line
   }
   temp.dna_sequence[i] = '\0'; // changed to i + 1
   return temp;
}

// Remove the given sequence from the invoking object if it exists. Return
// the modified sequence. If the given sequence is not found, return the
// first argument sequence unaltered.
DNASequence operator - (const DNASequence &arg1, const DNASequence &arg2)
{
    DNASequence temp = arg1;
   if (arg1.get_max_sequence() == 0)
       return arg2;
   if (arg2.get_max_sequence() == 0)
       return arg1;

   temp.max_sequence = arg1.get_max_sequence() - arg2.get_max_sequence();
   temp.dna_sequence = new char(temp.max_sequence + 1);
   int i = 0;
   for (int j = 0; j < arg1.get_max_sequence(); j++)
   {
       temp.dna_sequence[i] = arg1.dna_sequence[j];
       i++;
   }
   for (int j = 0; j < arg2.get_max_sequence(); j++)
   {
       temp.dna_sequence[i] = arg2.dna_sequence[j];
       i++;
   }
   temp.dna_sequence[i] = '\0';
   return temp;
}

// check if string is valid
bool DNASequence::isitvalid(string str) 
{
   // Check the string for characters 'A', 'a', 'T', 't', 'G', 'g', 'C', 'c'
   // return false if any characters in the string are different. You can
   // use any means you like, remember what we did with palindrome code to
   // avoid a big if statement.
   bool valid = false;
   for (int i = 0; i < str.length(); i++)
   {
       if (str[i] != 'A' && str[i] != 'a' && str[i] != 'T' && str[i] != 't' && str[i] != 'G' && str[i] != 'g' && str[i] != 'C' && str[i] != 'c')
           return false;          
   }
   return true;
}

// Implement the friend function to read in a nucleotide sequence made up
// of only the following characters: adenine (A), thymine (T), guanine (G)
// and cytosine (C). Assume case insensitive but convert to upper internally.
istream& operator >> (istream& ins, DNASequence& arg)
{
     // Read in a string and use the validate function above to ensure that
   // the string has only nucleotides and convert them all to upper case.

   string str;
   ins >> str;
   if (arg.isitvalid(str))
   {
       arg.max_sequence = str.length();
       arg.dna_sequence = new char(str.length()+1);
       int i = 0;
       for (i = 0; i < str.length(); i++)
       {
           arg.dna_sequence[i] = toupper(str[i]);
       }
       arg.dna_sequence[i] = '\0';
   }
   return ins;
}

// Implement the friend function to write out a nucleotide sequence. No blanks.
ostream& operator << (ostream& out, const DNASequence& arg)
{
   for (int i = 0; i < arg.get_max_sequence(); i++)
   {
       out << arg.dna_sequence[i];
   }
   out << endl;
   return out;
}


dna_main.cpp

/*
 * Test driver for DNAStrand with DNASequences
 * 
 *
 *
 */
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include "dnasequence.h"

using namespace std;

// int main()
//
// Implements the driver for the DNAStrand testing using DNASequences.
//
int main()
{
    int i = 0;
    int n;
    char rerun;
    // Implement your test functions here.

    //greeting 
    cout << "Welcome to CRISPR!" <<endl;
    cout << endl;
    do
    {


    // 1. Start a do-while loop that spans the rest of the instructions.

    // 2. Ask the user to enter the number of DNASequences needed for the CRISPR application.
        cout << "Enter the number of DNA sequences needed: ";
        cin >> n;

        // 3. Either declare a vector of DNASequence or a dynamic array where the user enters the number of elements.
        vector<DNASequence>DNA(n); //?

    // 4. In a for-loop, read in a DNASequence for each element in the array using >> operator.
        for(i = 0; i < n; i++)
         {
             cout << "Processing DNA sequence #" << i + 1 << endl;
             cout << "Enter the elements in sequence #" << i + 1 << ": ";
             cin >> DNA[i];  
         }
         /*
         cout << DNA[0];
         cout << endl;
         cout << DNA[1];
         cout << endl;
         DEBUG LINES
         */

    // 5. Declare a DNASequence called big_strand and add each element in the array to big_strand in a for-loop.


            DNASequence big_strand;

            for(int x = 0; x < n ; x++)
            { 
                big_strand = big_strand + DNA[x];
            }

    // 6. Print the final big_strand after the loop using the << operator.

        cout << "The contents in the big strand is: ";
        cout << big_strand;

    // 7. Declare two variables: one for a small sequence of bad_dna and one to hold the clean_strand.
    // NOTE: Make sure that clean_strand is set directly to big_strand when declared.

        DNASequence bad_dna;
        DNASequence clean_strand = big_strand;

        // 6 a. Test == operator
        cout << "Checking == operator ... " << endl;
        if(big_strand == clean_strand)
            cout << "Functioning properly\n";

        // 6 b. Test != operator
        cout << "Checking != operator... " << endl;
        if (big_strand != bad_dna)
            cout << "Functioning properly\n";



    // 8. Ask the user to enter the bad DNASequence to remove from big_strand and put it in the bad_dna variable.

        cout << "Enter a bad DNASequence to remove from big_strand: ";
        cin >> bad_dna;

    // 9. In a do-while loop add the following lines

        // 9 a. set the big_strand to the clean_strand
        // 9 b. subtract the bad_dna from big_strand and put the result in clean_strand
        do
        {
            big_strand = clean_strand;
            clean_strand = big_strand - bad_dna;
            cout << clean_strand;
        }while(clean_strand != big_strand);

    // 10. Use clean_strand != big_strand as the while condition so that it loops until the big_strand is clean.

    // 11. Print the clean_strand as you go and the final result.

        cout << "The contents in the clean strand is: " ; 
        cout << clean_strand;

    // 12. Test operator% with a copy of the big_strand to see if the result is the same as the loop above.

    // 13. Clean up array/vector
        DNA.clear();
    // 14. Ask the user to try again.
        cout << "Would you like to try again (y/n)?";
        cin >> rerun;

    }while(rerun == 'y' || rerun == 'Y');
    return 0;
}

标签: c++classdynamicoperator-overloading

解决方案


推荐阅读