2012-07-16 177 views
-1

下面是整個程序,請幫助我,我已經試過了一切,以找出內存到底是什麼。問題是一切運行完美,但有一些額外的字符打印輸出。內存分配和釋放

這裏是.h文件:

class MyString 
{ 
    public: 
      MyString(); 
      MyString(const char *message); 
      MyString(const MyString &source); 
      ~MyString(); 
      const void Print() const; 
      const int Length() const; 
      MyString& operator()(const int index, const char b); 
      char& operator()(const int i); 

      MyString& operator=(const MyString& rhs); 
      bool operator==(const MyString& other) const; 
      bool operator!=(const MyString& other) const; 
      const MyString operator+(const MyString& rhs) const; 
      MyString& operator+=(const MyString& rhs); 
      friend ostream& operator<<(ostream& output, const MyString& rhs); 
      const int Find(const MyString& other); 
      MyString Substring(int start, int length); 

    private: 
      char *String; 
      int Size; 


}; 

istream& operator>>(istream& input, MyString& rhs); 

.cpp文件:

MyString::MyString() 
{ 
    char temp[] = "Hello World"; 

    int counter(0); 
    while(temp[counter] != '\0') 
    { 
      counter++; 
    } 
    Size = counter; 
    String = new char [Size]; 
    for(int i=0; i < Size; i++) 
      String[i] = temp[i]; 

} 

//alternate constructor that allows for setting of the inital value of the string 

    MyString::MyString(const char *message) 
    { 
    int counter(0); 
    while(message[counter] != '\0') 
    { 
      counter++; 
    } 
    Size = counter; 
    String = new char [Size]; 
    for(int i=0; i < Size; i++) 
      String[i] = message[i]; 
} 

//copy constructor 
MyString::MyString(const MyString &source) 
{ 

    int counter(0); 
    while(source.String[counter] != '\0') 
    { 
     counter++; 
    } 
    Size = counter+1; 
    String = new char[Size]; 
    for(int i = 0; i <= Size; i++) 
      String[i] = source.String[i]; 


} 

//Deconstructor 
MyString::~MyString() 
{ 
    delete [] String; 
} 

//Length() method that reports the length of the string 
const int MyString::Length() const 
{ 
    int counter(0); 

    while(String[counter] != '\0') 
    { 
      counter ++; 
    } 
    return (counter); 
} 

/*Parenthesis operator should be overloaded to replace the Set and Get functions of your previous assignment. Note that both instances should issue exit(1) upon violation of the string array bounaries. 
*/ 

    MyString& MyString::operator()(const int index, const char b) 
    { 
    if(String[index] == '\0') 
    { 
      exit(1); 
    } 
    else 
    { 
      String[index] = b; 
    } 
} 

char& MyString::operator()(const int i) 
{ 
    if(String[i] == '\0') 
    { 
      exit(1); 
    } 
    else 
    { 
      return String[i]; 
    } 
} 
/*Assignment operator (=) which will copy the source string into the destination string. Note that size of the destination needs to be adjusted to be the same as the source. 
*/ 

MyString& MyString::operator=(const MyString& rhs) 
{ 
    if(this != &rhs) 
    { 
      delete [] String; 
      String = new char[rhs.Size]; 
      Size = rhs.Size; 

      for(int i = 0; i < rhs.Size+1 ; i++) 
      { 
        String[i] = rhs.String[i]; 
      } 
    } 

    return *this; 
} 
/*Logical comparison operator (==) that returns true iff the two strings are identical in size and contents. 
*/ 

    bool MyString::operator==(const MyString& other)const 
    { 
    if(other.Size == this->Size) {   
     for(int i = 0; i < this->Size+1; i++) 
      { 
        if(&other == this) 
          return true; 
      } 
    } 
    else 
      return false; 
} 

//Negated logical comparison operator (!=) that returns boolean negation of 2 

bool MyString::operator!=(const MyString& other) const 
{ 
    return !(*this == other); 
} 

//Addition operator (+) that concatenates two strings 

const MyString MyString::operator+(const MyString& rhs) const 
{ 
    char* tmp = new char[Size + rhs.Size +1]; 


    for(int i = 0; i < Size; i++) 
    { 
      tmp[i] = String[i]; 
    } 
    for(int i = 0; i < rhs.Size+1; i++) {   
     tmp[i+Size] = rhs.String[i]; 
    } 

    MyString result; 

    delete [] result.String; 
    result.String = tmp; 
    result.Size = Size+rhs.Size; 

    return result; 
} 
/*Addition/Assigment operator (+=) used in the following fashion: String1 += String2 to operate as String1 = String1 + String2 
*/ 

MyString& MyString::operator+=(const MyString& rhs) 
    { 
    char* tmp = new char[Size + rhs.Size + 1]; 

    for(int i = 0; i < Size; i++)  { 
      tmp[i] = String[i]; 
    } 
    for(int i = 0; i < rhs.Size+1; i++) 
    { 
      tmp[i+Size] = rhs.String[i]; 
    } 

    delete [] String; 
    String = tmp; 
    Size += rhs.Size; 

    return *this; 
} 

istream& operator>>(istream& input, MyString& rhs) 
{ 
    char* t; 
    int size(256); 
    t = new char[size]; 
    input.getline(t,size); 

    rhs = MyString(t); 
    delete [] t; 

    return input; 
} 

ostream& operator<<(ostream& output, const MyString& rhs) 
{ 
    if(rhs.String != '\0') 
    { 
      output << rhs.String; 
    } 
    else 
    { 
      output<<"No String to output\n"; 
    } 

    return output; 
} 






/*MyString::Find that finds a string in a larger string and returns the starting location of the substring. Note that your string location starts from 0 and ends at length -1. If the string is not found, a value of -1 will be returned 
*/ 

const int MyString::Find(const MyString& other) 
{ 

    int nfound = -1; 

    if(other.Size > Size) 
    { 
      return nfound; 
    } 
     int i = 0, j = 0;  
     for(i = 0; i < Size; i++) {    
     for(j = 0; j < other.Size; j++) {    
      if(((i+j) >= Size) || (String[i+j] != other.String[j])) 

        { 
          break; 
        } 

      } 

      if(j == other.Size) 
      { 

        return i; 

      } 

     } 


    return nfound; 
} 
/*MyString::Substring(start, length). This method returns a substring of the original string that contains the same characters as the original string starting at location start and is as long as length. 
*/ 

MyString MyString::Substring(int start, int length) 
{ 
    char* leo = new char[length+1]; 
    for(int i = start; i < start + length+1; ++i) 
    { 
      leo[i-start] = String[i]; 
    } 

    MyString sub; 
    delete [] sub.String;  sub.String = leo;  sub.Size = Size; 
    return sub; 
} 

    //Print() method that prints the string 

const void MyString::Print() const 
{ 

    for(int i=0; i < Size; i++) 
    { 
      cout<<String[i]; 
    } 
    cout<<endl; 
} 

的main.cpp的文件:

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

    MyString String1; 

    const MyString ConstString("Target string"); //Test of alternate constructor 

    MyString SearchString; //Test of default constructor that should set "Hello World". 

MyString TargetString (String1); //Test of copy constructor 


    cout << "Please enter two strings. "; 
    cout << "Each string needs to be shorter than 256 characters or terminated by /\n." << endl; 
cout << "The first string will be searched to see whether it contains exactly the second string. " << endl; 

    cin >> SearchString >> TargetString; // Test of cascaded string-extraction operator 






    if(SearchString.Find(TargetString) == -1) { 

    cout << TargetString << " is not in " << SearchString << endl; 
    } 

    else { 

    cout << TargetString << " is in " << SearchString << endl; 

    cout << "Details of the hit: " << endl; 

    cout << "Starting position of the hit: " << SearchString.Find(TargetString) << endl; 
    cout << "The matching substring is: " << SearchString.Substring(SearchString.Find(TargetString), TargetString.Length()-1)<<"\n"; 
    } 
    return 0; 

} 

運行你得到這個程序:

請輸入兩個字符串。每個字符串需要少於256個字符或由/ 終止。 第一個字符串將被搜索以查看它是否包含第二個字符串。

首先

真正

REALT世界是不是首先

請幫助!

+1

[減少問題。](http://dev.rootdirectory.de/wiki/MacheteDebugging)這比我們在這裏可以做的任何調試都要有用得多。 – DevSolar 2012-07-16 14:43:58

+0

這個問題太長了,如果你提出一個更簡潔的問題會更容易。 – 2012-07-16 22:31:37

回答

0

嘗試在MyString::MyString(const char *message)構造

+0

你的意思是喜歡傳入的字符串嗎? – user1363061 2012-07-16 15:59:51

+1

是的。 c和C++字符串通常以'\ 0'結尾。 – 2012-07-16 16:02:38

+0

與該構造函數傳入的字符串由以下定義:const MyString ConstString(「Target string」);相反,它應該是常量MyString ConstString(「目標字符串\ 0」); ??對不起,我對這個有點新了 – user1363061 2012-07-16 16:09:54

0

在你的字符串末尾添加「\ 0」 @ Sam的答案是正確的。我將加入它來幫助你瞭解發生了什麼。

C和C++字符串是遵循慣例,該字符串被終止\0,有時被稱爲NUL(空),這是一個字符真字符陣列,其中所有位都爲0

您的代碼獲得第一部分的權利,因爲它創建了一個字符數組。但是,您不應用約定該字符串必須爲NUL終止。

然後,您將一個不遵循NUL終止約定的字符串傳遞給cout,其中確實遵循該約定。換句話說,它貫穿字符串,將每個字符打印到stdout,直到它在內存中穿過字符\0發生。它終於真的很幸運。如果輸出的字符數組中沒有\0,則它將繼續前進,直到到達不屬於您的程序的內存地址並且出現分段錯誤。

+0

非常感謝!所以我的猜測是通過對所有構造函數說Size = counter +1來添加NUL字符。然後,我可能不得不在程序的後面更改函數的大小,例如我的子字符串函數。 – user1363061 2012-07-17 13:01:08