String 内存分配和释放

String 内存分配和释放,string,oop,memory-management,memory-leaks,String,Oop,Memory Management,Memory Leaks,这是整个程序,请帮助我,我已经尝试了一切,以找出到底是什么与内存。问题是,一切都运行得很好,但输出中还有一些额外的字符 以下是.h文件: class MyString { public: MyString(); MyString(const char *message); MyString(const MyString &source); ~MyString();

这是整个程序,请帮助我,我已经尝试了一切,以找出到底是什么与内存。问题是,一切都运行得很好,但输出中还有一些额外的字符

以下是.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);
类MyString
{
公众:
MyString();
MyString(常量字符*消息);
MyString(constmystring&source);
~MyString();
常量void Print()常量;
常量int Length()常量;
MyString&operator()(常量int index,常量char b);
字符和运算符()(常量int i);
MyString和operator=(const MyString和rhs);
布尔运算符==(常量MyString和其他)常量;
布尔运算符!=(常量MyString和其他)常量;
常量MyString运算符+(常量MyString&rhs)常量;
MyString和operator+=(const MyString和rhs);
friend ostream&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;
 }
 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;

 }
MyString::MyString()
{
char temp[]=“你好,世界”;
整数计数器(0);
while(临时[计数器]!='\0')
{
计数器++;
}
尺寸=计数器;
字符串=新字符[大小];
对于(int i=0;iSize+1;i++)
{
如果(&其他==此)
返回true;
}
}
其他的
返回false;
}
//求反逻辑比较运算符(!=),返回2的布尔求反
bool MyString::operator!=(const MyString和其他)const
{
返回!(*此==其他);
}
//连接两个字符串的加法运算符(+)
const MyString MyString::operator+(const MyString&rhs)const
{
char*tmp=新字符[Size+rhs.Size+1];
对于(int i=0;i>(istream和input、MyString和rhs)
{
char*t;
整数大小(256);
t=新字符[大小];
输入.getline(t,大小);
rhs=MyString(t);
删除[]t;
返回输入;
}

ostream&operator尝试在
MyString::MyString(const char*message)
构造函数中的字符串末尾添加“\0”

@Sam的答案是正确的。我将添加它以帮助您了解发生了什么

C和C++字符串是遵循字符串“终止”的一个惯例,即“代码> > 0”/代码>,有时称为NUL(NULL),这是一个字符,所有位都是0。 代码的第一部分是正确的,因为它创建了一个字符数组。但是,您没有应用字符串必须以NUL结尾的约定


然后,您将一个不遵循NUL终止约定的字符串传递给遵循该约定的
cout
。换句话说,它在字符串中运行,将每个字符打印到
stdout
,直到它发生在内存中的字符
\0
上。实际上,它终止是相当幸运的。如果如果e不是它输出的字符数组中的
\0
,它将继续运行,直到到达一个不属于您的程序的内存地址,并且由于分段错误而失败。

这将比我们在这里进行的任何调试都更有帮助。这个问题太长了,如果您给出一个更成功的cinct question.您的意思是像传入的字符串一样吗?使用该构造函数传入的字符串由以下定义:const MyString ConstString(“目标字符串”);因此,它应该是const MyString ConstString(“目标字符串\0”)很抱歉,我有点不熟悉这个我相信在字符串的末尾已经有了一个
\0
,比如
“Hello World”
哦,好吧,那么我就必须更改我的函数了?非常感谢!所以我想对所有构造函数添加NUL字符,比如Size=counter+1。然后,我可能需要在程序的后面更改函数中的大小,例如我的子字符串函数。