0

我正在尝试使用指针将工作的静态 String 类转换为动态 String 类,但是当我实现指针时,它会引发分段错误错误。下面的代码:

mystring1.h:

//File: mystring1.h
// Declaration file for user-defined String class.


#ifndef _MYSTRING_H
#define _MYSTRING_H
#include<iostream>
#include <cstring>
using namespace std;

#define MAX_STR_LENGTH  200


class String {
public:
  String();
  String(const char *s);  // a conversion constructor   
  void append(const String &str);

  //deconstructor
  ~String();

  //copy constructor
  String (const String & origString);

  //assignment operator overload
  String operator =(const String &origString);

  // Relational operators
  bool operator >(const String &str) const;
  bool operator <(const String &str) const;    

  String operator +=(const String &str);      

  void print(ostream &out) const;    
  int length() const;

  char operator [](int i) const;  // subscript operator 



private:
    char *contents;
    int len;
    //int capacity;
};

ostream & operator<<(ostream &out, const String & r); // overload ostream operator "<<" - External!  


#endif /* not defined _MYSTRING_H */

mystring1.cpp:

//File: mystring1.h
// Implementation file for user-defined String class.

#include "mystring1.h"


String::String()
{
  contents[0] = '\0';
  len = 0;
}

String::String(const char s[])
{
  len = strlen(s);
  contents = new char[len + 1];
  strcpy(contents, s);
}



void String::append(const String &str)
{
  strcat(contents, str.contents);
  len += str.len;
}

//deconstructor
String::~String()
{
  delete [] contents;
}

//copy constructor
String::String(const String &origString)
{
  len = origString.len;
  contents = new char[len + 1];

  for (int i = 0; i < len; i++)
  {
    contents[i] = origString.contents[i];
  }
}

//assignment operator overload
String String::operator =(const String &origString)
{
  if (this != &origString)
  {
    len = origString.len;
    delete [] contents;
    contents = new char[len + 1];

    for (int i = 0; i < len; i++)
    {
      contents[i] = origString.contents[i];
    }
  }

  return *this;
}


bool String::operator >(const String &str) const
{
  return strcmp(contents, str.contents) > 0;
}

bool String::operator <(const String &str) const
{
  return strcmp(contents, str.contents) < 0;
}


String String::operator +=(const String &str)
{
    append(str);
    return *this;
}

void String::print(ostream &out) const
{
  out << contents;
}

int String::length() const
{
  return len;
}

char String::operator [](int i) const
{
  if (i < 0 || i >= len) {
    cerr << "can't access location " << i
         << " of string \"" << contents << "\"" << endl;
    return '\0';
  }
  return contents[i];
}

ostream & operator<<(ostream &out, const String & s) // overload ostream operator "<<" - External!
{ 
    s.print(out);
    return out;
}

作业 5 司机:

/**
 * cmpsc122 Assignment 5 test file
 * File Name: Assign5driver.cpp
 *
 * Description: This program demonstrates a basic String class that implements
 * dynamic allocation and operator overloading.
 *
 */

#include <iostream>
#include "mystring1.h"
using namespace std;


/*************************** Main Program **************************/

int main()
{
  String str1, str2("dog");  // Using constructor for initial strings
  char s1[100], s2[100];              // Some C strings.

  // Print out initial strings

  cout << "Initial values:" << endl;
  cout << "str1 holds \"" << str1 << "\" (length = " << str1.length() << ")" << endl;
  cout << "str2 holds \"" << str2 << "\" (length = " << str2.length() << ")" << endl;

  // Inputs some new strings in them

  cout << "\nEnter a value for str1 (no spaces): ";
  cin >> s1;
  str1 = s1;

  cout << "\nEnter a value for str2 (no spaces): ";
  cin >> s2;
  str2 = s2;


  cout << "\nAfter assignments..." << endl;
  cout << "str1 holds \"" << str1 << "\" (length = " << str1.length() << ")" << endl;
  cout << "str2 holds \"" << str2 << "\" (length = " << str2.length() << ")" << endl;

  // Get some elements...

  int i;

  cout << "\nEnter which element of str1 to display: ";
  cin >> i;
  cout << "Element #" << i << " of str1 is '" << str1[i] << "'" << endl;

  cout << "\nEnter which element of str2 to display: ";
  cin >> i;
  cout << "Element #" << i << " of str2 is '" << str2[i] << "'" << endl;

  // Concate some strings

  cout << "\nEnter a value to append to str1 (no spaces): ";
  cin >> s1;
 // str1.append(s1); // Actually, the cstring is converted to String object here by the constructor
  str1 += s1;   // same as above

  cout << "\nEnter a value to append to str2 (no spaces): ";
  cin >> s2;
  str2 += s2;



  cout << "\nAfter appending..." << endl;
  cout << "str1 holds \"" << str1 << "\" (length = " << str1.length() << ")" << endl;
  cout << "str2 holds \"" << str2 << "\" (length = " << str2.length() << ")" << endl;

  // Compare strings...

  cout << "\nComparing str1 and str2..." << endl;

  cout << "\"";

  cout<< str1;   // test the overloading of ostream operator <<

  cout << "\" is ";

  if (str1 < str2) {      // test the overloading of comparison operator <
    cout << "less than";
  } else if (str1 > str2) {
    cout << "greater than";
  } else {
    cout << "equal to";
  }

  cout << " \"";
  cout << str2;
  cout << "\"" << endl;

  cout << "\ntest the = operator, after str1 = str2; "<< endl;

  str1 = str2;

 cout << "str1 holds \"" << str1 << "\" (length = " << str1.length() << ")" << endl;
  cout << "str2 holds \"" << str2 << "\" (length = " << str2.length() << ")" << endl;

  str1 += s1;

  cout << "\nAfter str1 = str1 + s1: "<< endl;

  cout << "str1 holds \"" << str1 << "\" (length = " << str1.length() << ")" << endl;
  cout << "str2 holds \"" << str2 << "\" (length = " << str2.length() << ")" << endl;

  String str3(str2);
  cout << "\ntest the copy constructor, after str4(str3);"<< endl;

  cout << "str2 holds \"" << str2 << "\" (length = " << str2.length() << ")" << endl;
  cout << "str3 holds \"" << str3 << "\" (length = " << str3.length() << ")" << endl;

  cout << "\nafter appending str2 by str1" << endl;
  str2 += str1;
  cout << "str2 holds \"" << str2 << "\" (length = " << str2.length() << ")" << endl;
  cout << "str3 holds \"" << str3 << "\" (length = " << str3.length() << ")" << endl;

  cout<< "\nstr3 are not changed. Type any letter to quit." << endl;

  char q;

  cin >> q;

  return 0;
}

任何帮助将不胜感激,我已尽我所能,我对分段错误原因的研究并没有多大帮助。

4

1 回答 1

1

您的实现中有几个显而易见的错误:

  1. 默认构造函数使用未初始化的contents指针。
  2. ::append()方法在执行之前不确保目标缓冲区中有足够的空间strcat
  3. 复制构造函数和::operator=()方法不会NUL终止contents缓冲区。

可能还有更多。

g++ -fsanitize=address ...您应该使用并修复它发现的所有错误来构建您的测试程序。

您还应该使用-Wall -Wextra标志构建程序,并修复它产生的所有警告。

于 2020-02-16T21:37:06.763 回答