当我在析构函数中没有调用delete [] buf的程序时,我的程序运行良好。但是,当我包含它时,程序在输出开始时崩溃。 这是我的文件。
// string.cpp #include“ String.h” #包括 #包括 下游csis;
String::String() {
buf = "\0";
length = 0;
}
String::String(const char* tar) {
int temp = strlen(tar);
length = temp;
buf = new char[length + 1];
buf[length] = '\0';
for (int i = 0; i < length; i++){
buf[i] = tar[i];
}
}
String::String(char a) {
length = 1;
buf = new char[length+1];
buf[length] = '\0';
buf[0] = a;
}
String::String(int x) {
int alloc = x;
if (x < 0) {
alloc = 0;
}
buf = new char[alloc+1];
length = x;
buf[0] = '\0';
}
String::String(const String& a) {
length = a.length;
buf = new char[length+1];
for (int i = 0; i < length; i++) {
buf[i] = a.buf[i];
}
}
String::String(char a, int x) {
buf = new char[x+1];
for (int i = 0; i < x; i++) {
buf[i] = a;
}
buf[x] = '\0';
length = strlen(buf);
}
String::~String() {
delete buf;
}
String& String::operator=(const String& tar) {
buf = new char[tar.length+1];
strcpy(buf, tar.buf);
length = tar.length;
buf[length] = '\0';
return *this;
}
String& String::operator=(const char* chr) {
buf = (char*)chr;
length = int(strlen(chr));
return *this;
}
String operator+(const String& a, const String& b) {
String sum;
int size = a.length + b.length;
sum.buf = new char[size+1];
sum.length = size;
for (int i = 0; i < a.length; i++) {
sum.buf[i] = a.buf[i];
}
int j = 0;
for (int i = a.length; i < size; i++) {
sum.buf[i] = b.buf[j];
j++;
}
sum.buf[size] = '\0';
return sum;
}
String operator+(const String& tar, const char* c) {
String sum;
int size = int(strlen(c)) + tar.length;
sum.buf = new char[size+1];
sum.length = size;
for (int i = 0; i < tar.length; i++) {
sum.buf[i] = tar.buf[i];
}
int j = 0;
for (int i = tar.length; i < size; i++) {
sum.buf[i] = c[j];
j++;
}
sum.buf[size] = '\0';
return sum;
}
String operator+(const char* c, const String& tar) {
String sum;
int size = int(strlen(c)) + tar.length;
sum.buf = new char[size+1];
sum.length = size;
for (int i = 0; i < int(strlen(c)); i++) {
sum.buf[i] = c[i];
}
int j = 0;
for (int i = strlen(c); i < size; i++) {
sum.buf[i] = tar.buf[j];
j++;
}
sum.buf[size] = '\0';
return sum;
}
String operator+(const String& tar, char c) {
String sum;
int size = 1 + tar.length;
sum.buf = new char[size];
sum.length = size;
for (int i = 0; i < tar.length; i++) {
sum.buf[i] = tar.buf[i];
}
int j = 0;
for (int i = tar.length; i < size; i++) {
sum.buf[i] = c;
j++;
}
sum.buf[size] = '\0';
return sum;
}
String operator+(char c, const String& tar) {
String sum;
int size = 1 + tar.length;
sum.buf = new char[size+1];
sum.length = size;
for (int i = 0; i < 1; i++) {
sum.buf[i] = c;
}
int j = 0;
for (int i = 1; i < size; i++) {
sum.buf[i] = tar.buf[j];
j++;
}
sum.buf[size] = '\0';
return sum;
}
String& String::operator+=(const String& tar) {
String temp = *this;
temp = temp + tar;
*this = temp;
return *this;
}
String& String::operator+=(const char c) {
String temp = *this;
temp = temp + c;
*this = temp;
return *this;
}
String String::operator+() const {
String sum;
sum.length = length;
sum.buf = new char[sum.length+1];
strcpy(sum.buf, buf);
for (int i = 0; i < length; i++) {
sum.buf[i] = toupper(buf[i]);
}
sum.buf[length] = '\0';
return sum;
}
int operator==(const String & tar, const String& tar2) {
int check = 0;
if (strcmp(tar.buf, tar2.buf) == 0) {
check += 1;
}
else if (strcmp(tar.buf, tar2.buf) != 0) {
check = 0;
}
return check;
}
int operator!=(const String& tar, const String& tar2) {
int check = 0;
if (!(strcmp(tar.buf, tar2.buf) == 0)) {
check += 1;
}
else if (!(strcmp(tar.buf, tar2.buf) != 0)) {
check = 0;
}
return check;
}
int operator<(const String& a, const String& b) {
int check = 0;
if (a.length < b.length) {
check += 1;
}
return check;
}
int operator<=(const String& a, const String& b) {
int check = 0;
if (a.length <= b.length) {
check += 1;
}
return check;
}
int operator>(const String& a, const String& b) {
int check = 0;
if (a.length > b.length) {
check += 1;
}
return check;
}
int operator>=(const String& a, const String& b) {
int check = 0;
if (a.length >= b.length) {
check += 1;
}
return check;
}
char& String::operator[](int x) {
int out;
if (x >= 0 && x < length) {
out = x;
}
else if (!(x >= 0 && x < length)) {
int output = NULL;
cout << "ERROR: Invalid Index with [] operator." << endl;
csis << "ERROR: Invalid Index with [] operator." << endl;
out = NULL;
}
return buf[out];
}
char* operator+(const String& a, int x) {
return &a.buf[x];
}
char* operator+(int x, const String& a) {
return &a.buf[x];
}
String String::operator++(int val) {
String temp;
temp = *this;
for (int i = 0; i < temp.length; i++) {
temp.buf[i] = temp.buf[i] + 1;
}
return temp;
}
String String::operator--(int val) {
String temp;
temp = *this;
for (int i = 0; i < temp.length; i++) {
temp.buf[i] = temp.buf[i] - 1;
}
return temp;
}
String String::operator++() {
String temp = *this;
for (int i = 0; i < temp.length; i++) {
temp.buf[i] = (temp.buf[i] + 1);
}
return temp;
}
String String::operator--() {
String temp = *this;
for (int i = 0; i < temp.length; i++) {
temp.buf[i] = (temp.buf[i] - 1);
}
return temp;
}
int String::getLength() {
return length;
}
String String::substr(int a, int b) {
String temp = *this;
char *fill = new char[b+1];
int i = a;
int x = 0;
while (x <= b) {
fill[i] = temp.buf[i];
i++;
x++;
}
temp.buf = fill;
temp.buf[length] = '\0';
return temp;
}
void String::print() {
cout << """";
csis << """";
for (int i = 0; i < length; i++) {
cout << buf[i];
csis << buf[i];
}
cout << """";
csis << """";
cout << " Length: " << length << endl;
csis << " Length: " << length << endl;
}
ostream& operator<<(ostream& o, const String& tar) {
for (int i = 0; i < tar.length; i++) {
o << tar.buf[i];
}
return o;
}
这里是字符串。h
//string.h
#ifndef _STRING_H
#define _STRING_H
#include <iomanip>
#include <stdlib.h>
#include <iostream>
using namespace std;
class String {
protected:
int length;
char* buf;
public:
String();
String(const char*);
String(char a);
String(int x);
String(const String&);
String(char a, int x);
~String();
// Operator Overload
String& operator=(const String& tar);
String& operator= (const char*);
friend String operator+(const String& a, const String& b);
friend String operator+(const String&, const char*);
friend String operator+(const char* c, const String& tar);
friend String operator+(const String&, char c);
friend String operator+(char c, const String& tar);
String& operator+=(const String& tar);
String& operator+=(const char c);
String operator+() const;
friend int operator==(const String&, const String&);
friend int operator!=(const String&, const String&);
friend int operator<(const String&, const String&);
friend int operator<=(const String&, const String&);
friend int operator>(const String&, const String&);
friend int operator>=(const String&, const String&);
char& operator[](int);
friend char* operator+(const String&, int);
friend char* operator+(int, const String&);
String operator++();
String operator--();
String operator++(int);
String operator--(int);
int getLength();
String substr(int a, int b);
void print();
friend ostream& operator<<(ostream&, const String&);
};
#endif
这里是StringDriver.cpp
// StringDriver.cpp
// MATTHEW BUTNER
// ID: 011029756
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include "StringDriver.h"
using namespace std;
ofstream csis;
int main() {
csis.open("csis.txt");
test1();
test2();
test3();
test4();
test5();
test6();
test7();
test8();
test9();
test10();
test11();
test12();
test13();
test14();
test15();
test16();
test17();
test18();
test19();
test20();
csis.close();
}
void test1() {
cout << "1. Testing S1: String default ctor." << endl << endl;
csis << "1. Testing S1: String default ctor." << endl << endl;
String s1;
s1.print();
wait();
}
void test2() {
cout << "2. Testing S2: String one arg (char *) ctor." << endl << endl;
csis << "2. Testing S2: String one arg (char *) ctor." << endl << endl;
String s2("ABC");
s2.print();
wait();
}
void test3() {
cout << "3. Testing S3: String one arg (char) ctor." << endl << endl;
csis << "3. Testing S3: String one arg (char) ctor." << endl << endl;
String s3('Z');
s3.print();
wait();
}
void test4() {
cout << "4. Testing S4: String one arg (int) ctor." << endl << endl;
csis << "4. Testing S4: String one arg (int) ctor." << endl << endl;
String s4(10);
s4.print();
wait();
}
void test5() {
cout << "5. Testing S5, T5: String copy ctor." << endl << endl;
csis << "5. Testing S5, T5: String copy ctor." << endl << endl;
String s5("Purple Rain");
s5.print();
String t5(s5);
t5.print();
wait();
}
void test6() {
cout << "6. Testing S6: String two arg (char, int) ctor." << endl << endl;
csis << "6. Testing S6: String two arg (char, int) ctor." << endl << endl;
String s6('*', 10);
s6.print();
wait();
}
void test7() {
cout << "7. Testing S7, T7, U7: String assignment." << endl << endl;
csis << "7. Testing S7, T7, U7: String assignment." << endl << endl;
String s7("Sally Ride"), t7, u7;
t7 = u7 = s7;
s7.print();
t7.print();
u7.print();
wait();
}
void test8() {
cout << "8. Testing S8: String assignment." << endl << endl;
csis << "8. Testing S8: String assignment." << endl << endl;
String s8("ABC");
s8 = s8;
s8.print();
wait();
}
void test9() {
cout << "9. Testing S9: Implicit type conversion." << endl << endl;
csis << "9. Testing S9: Implicit type conversion." << endl << endl;
String s9;
s9 = "ABC";
s9.print();
wait();
}
void test10() {
cout << "10. Testing S10, T10, U10: String concatenation." << endl << endl;
csis << "10. Testing S10, T10, U10: String concatenation." << endl << endl;
String s10("DEF");
String t10('H');
String u10("ABC" + s10 + "G" + t10 + 'I');
u10.print();
String v10('X' + u10);
v10.print();
wait();
}
void test11() {
cout << "11. Testing S11, T11: String concatenation." << endl << endl;
csis << "11. Testing S11, T11: String concatenation." << endl << endl;
String s11('A');
String t11("BC");
s11 += s11 += t11 += 'D';
s11.print();
t11.print();
wait();
}
void test12() {
cout << "12. Testing S12, T12: String unary operator." << endl << endl;
csis << "12. Testing S12, T12: String unary operator." << endl << endl;
String s12("Unary +");
String t12(+s12);
s12.print();
t12.print();
s12 = +s12;
s12.print();
wait();
}
void test13() {
cout << "13. Testing S13, T13: String comparison operators." << endl << endl;
csis << "13. Testing S13, T13: String comparison operators." << endl << endl;
String s13("ABC"), t13("ABCD");
s13.print();
t13.print();
cout << endl;
cout << "== " << (s13 == t13 ? "True" : "False") << endl;
cout << "!= " << (s13 != t13 ? "True" : "False") << endl;
cout << "< " << (s13 < t13 ? "True" : "False") << endl;
cout << "<= " << (s13 <= t13 ? "True" : "False") << endl;
cout << "> " << (s13 > t13 ? "True" : "False") << endl;
cout << ">= " << (s13 >= t13 ? "True" : "False") << endl;
csis << endl;
csis << "== " << (s13 == t13 ? "True" : "False") << endl;
csis << "!= " << (s13 != t13 ? "True" : "False") << endl;
csis << "< " << (s13 < t13 ? "True" : "False") << endl;
csis << "<= " << (s13 <= t13 ? "True" : "False") << endl;
csis << "> " << (s13 > t13 ? "True" : "False") << endl;
csis << ">= " << (s13 >= t13 ? "True" : "False") << endl;
wait();
}
void test14() {
cout << "14. Testing S14: Overloaded subscript operator." << endl << endl;
csis << "14. Testing S14: Overloaded subscript operator." << endl << endl;
String s14("C++ is fun.");
for (int i = -1; i <= s14.getLength(); i++) {
char& ch = s14[i];
if (ch != '\0')
++ch;
}
s14.print();
wait();
}
void test15() {
cout << "15. Testing S15: Pointer notation." << endl << endl;
csis << "15. Testing S15: Pointer notation." << endl << endl;
String s15("ABCDE");
for(int i = 0; i < s15.getLength(); i++)
++(*(s15+i));
for (int j = 0; j < s15.getLength(); j++) {
cout << *(j + s15);
csis << *(j + s15);
}
cout << endl;
csis << endl;
wait();
}
void test16() {
cout << "16. Testing S16, T16, U16, V16, W16, X16, Y16, Z16: Increment and decrement operators." << endl << endl;
csis << "16. Testing S16, T16, U16, V16, W16, X16, Y16, Z16: Increment and decrement operators." << endl << endl;
String s16("ABC");
String t16(++s16);
s16.print();
t16.print();
String u16("ABC");
String v16(u16++);
u16.print();
v16.print();
String w16("ABC");
String x16(--w16);
w16.print();
x16.print();
String y16("ABC");
String z16(y16--);
y16.print();
z16.print();
wait();
}
void test17() {
cout << "17. Testing S17, T17: Substr function." << endl << endl;
csis << "17. Testing S17, T17: Substr function." << endl << endl;
String s17("All You Need Is Love"), t17;
t17 = s17.substr(4, 8);
s17.print();
t17.print();
wait();
}
void test18() {
cout << "18. Testing S18, T18: Output function." << endl << endl;
csis << "18. Testing S18, T18: Output function." << endl << endl;
String s18("Red-");
String t18("Green-");
String u18("Blue");
cout << s18 << t18 << u18;
csis << s18 << t18 << u18;
cout << endl;
csis << endl;
wait();
}
void test19() {
cout << "19. Testing S19, T19, U19: ReverseString class." << endl << endl;
csis << "19. Testing S19, T19, U19: ReverseString class." << endl << endl;
ReverseString s19("Computer");
ReverseString t19;
t19 = ~s19;
s19.print();
t19.print();
ReverseString u19(~~s19);
u19.print();
wait();
}
void test20() {
cout << "20. Testing S20, T20, U20: CaseString class." << endl << endl;
csis << "20. Testing S20, T20, U20: CaseString class." << endl << endl;
CaseString s20("BaLLooN");
CaseString t20;
t20 = s20;
s20.print();
t20.print();
CaseString u20(s20);
u20.print();
wait();
}
void wait() {
char buf;
cout << endl << "Press any key to continue." << endl;
csis << endl << endl;
cin.get(buf);
}
问题在于string.cpp中的析构函数,当我有一个空的析构函数时,一切都很好,但是当我包含delete buf时,它将使程序崩溃。另外,这是其他.h和.cpp文件:
//ReverseString.h
#ifndef _REVERSESTRING_H
#define _REVERSESTRING_H
#include "String.h"
#include <iostream>
class ReverseString : public String {
public:
ReverseString();
ReverseString(const ReverseString& tar);
ReverseString(const char* c);
ReverseString& operator=(const ReverseString&);
ReverseString operator~();
};
#endif
下一个文件
//ReverseString.cpp
#include "ReverseString.h"
extern ostream csis;
ReverseString::ReverseString() : String() {
}
ReverseString::ReverseString(const ReverseString& tar) : String(tar) {
}
ReverseString::ReverseString(const char* c) : String(c) {
}
ReverseString& ReverseString::operator=(const ReverseString& tar) {
length = tar.length;
buf = tar.buf;
buf[length] = '\0';
return *this;
}
ReverseString ReverseString::operator~() {
ReverseString reverse;
reverse.length = length;
reverse.buf = new char[length];
int j = length - 1;
for (int i = 0; i < length; i++) {
reverse.buf[i] = buf[j];
j--;
}
return reverse;
}
CaseString.h
#ifndef _CASESTRING_H
#define _CASESTRING_H
#include "String.h"
#include <iostream>
class CaseString : public String {
protected:
char* upper;
char* lower;
public:
CaseString();
CaseString(const CaseString& tar);
CaseString(const char* c);
CaseString& operator=(const CaseString& c);
void print();
~CaseString();
};
#endif
CaseString.cpp
#include "CaseString.h"
#include <fstream>
extern ofstream csis;
CaseString::CaseString() : String() {
}
CaseString::CaseString(const CaseString& tar) : String(tar) {
upper = tar.upper;
lower = tar.lower;
buf = tar.buf;
length = tar.length;
}
CaseString::CaseString(const char* c) : String(c) {
lower = new char[int(strlen(c))];
upper = new char[int(strlen(c))];
int losize = strlen(c);
char* getLow = new char[losize];
for (int i = 0; i < losize; i++) {
getLow[i] = tolower(c[i]);
}
char* getHi = new char[losize];
for (int i = 0; i < losize; i++) {
getHi[i] = toupper(c[i]);
}
lower = getLow;
upper = getHi;
lower[losize] = '\0';
upper[losize] = '\0';
}
CaseString& CaseString::operator=(const CaseString& tar) {
if (&tar != this) {
String::operator=(tar);
buf = tar.buf;
length = tar.length;
lower = tar.lower;
upper = tar.upper;
}
return *this;
}
void CaseString::print() {
cout << "\"" << buf << "\"" << " " << "Length = " << length << " |" << "Lower = " << lower << " |" << "Upper = " << upper << endl;
csis << "\"" << buf << "\"" << " |" << "Length = " << length << " |" << "Lower = " << lower << " |" << "Upper = " << upper << endl;
}
CaseString::~CaseString() {
}
答案 0 :(得分:2)
我看到了几个问题。
主要问题是您有时会向buf
分配一个指向字符串的指针(您的默认构造函数就是这样的一个地方,并且至少还有一个)。这是您不想删除的指针。您需要始终为buf
分配内存,或者需要某种方法来判断您是否拥有该指针,应该将其删除。
另一个问题是,由于您使用new []
,因此需要在析构函数中使用delete [] buf
。
在复制构造函数中,您不会在上等缓冲区的末尾复制nul字节。