c++ - “检测到 CRT ......堆损坏”错误与析构函数
问题描述
我正在尝试在我的班级上使用析构函数,但它给了我一个错误:
CRT 检测到应用程序在结束或堆缓冲区后写入内存
以下是完整代码:
#include <iostream>
#include <string.h>
using namespace std;
class Autor {
char* name;char* surname;
public:
Autor(char* nam, char* surnam) {
name = new char[strlen(nam)];
surname = new char[strlen(surnam)];
strcpy(name, nam);
strcpy(surname, surnam);
};
Autor() {
name = new char;
surname = new char;
*name = '-';
*surname = '-';
};
Autor(Autor& a)
{
name = new char[strlen(a.name)+1];
surname = new char[strlen(a.surname)+1];
strcpy(name, a.name);
strcpy(surname, a.surname);
};
char* getName() { return name; };
char* getSurname() { return surname; };
Autor& setName(char* nam) {
name = new char[strlen(nam)];
strcpy(name, nam);
return *this;
};
Autor& setSurname(char* surnam) {
surname = new char[strlen(surnam)];
strcpy(surname, surnam);
return *this;
};
void print1() {
cout << "First print type: " << name << " "<< surname<<"\n";
};
void print2()
{
cout << "Second print type: " << "Author, name: " << name <<"\n";
};
~Autor() {
if (name)
{
delete[] name;
}
if (surname)
{
delete[] surname;
}
};
};
class Book {
char* name;
char* codeUDK;
Autor auth;
int year;
int numPages;
public:
Book(char* nam, char* code, Autor a, int yea, int numP)
{
name = new char[strlen(nam)];
codeUDK = new char[strlen(code)];
strcpy(name, nam);
strcpy(codeUDK, code);
auth = a;
year = yea;
numPages = numP;
};
Book()
{
name = new char;
strcpy(name, "x");
codeUDK = new char[2];
strcpy(codeUDK, "x");
char* nameAuth;
nameAuth = new char;
char* surnameAuth;
strcpy(nameAuth,"x");
surnameAuth = new char[2];
strcpy(surnameAuth, "x");
auth.setName(nameAuth);
auth.setSurname(surnameAuth);
year = 0;
numPages = 0;
};
char* getName() { return name; };
char* getCode() { return codeUDK; };
Autor getAuth() { return auth; };
int getYear(){ return year;};
int getNumPages() { return numPages; };
Book& setName(char* nam)
{
name = new char[strlen(nam)];
strcpy(name, nam);
return *this;
};
Book& setCode(char* code)
{
codeUDK = new char[strlen(code)];
strcpy(codeUDK, code);
return *this;
};
Book& setAuth(Autor a)
{
auth = a;
return *this;
};
Book& setYear(int yea)
{
year = yea;
return *this;
};
Book& setNumPages(int num)
{
numPages = num;
return *this;
};
Book(Book& a)
{
name = new char[strlen(a.name)+1];
strcpy(name, a.name);
codeUDK = new char[strlen(a.codeUDK)+1];
strcpy(codeUDK, a.codeUDK);
auth = a.auth;
year = a.year;
numPages = a.numPages;
}
~Book()
{
if (name)
{
delete[] this->name;
}
if (codeUDK)
{
delete[] this->codeUDK;
}
}
void print1() {
cout <<"First print type: "<< name << " code: " << codeUDK << " author's name: " << auth.getName() << " author's surname: " << auth.getSurname() << " year of writing " << year << " amount of pages: " << numPages<<"\n";
};
void print2() {
cout << "Second print type: " << "Book, name and author: " << name << ", Author: " << auth.getName() << auth.getSurname();
};
};
int main()
{
char nameA[20] = "George", surnameA[20] = "Orwell";
Autor auth;
cout << "enter name and surname: ";
auth.setName(nameA).setSurname(surnameA);
Autor auth1(auth);
auth.print1();
auth.print2();
cout << "\ncopied author:\n";
auth1.print1();
auth1.print2();
Book myBook;
char nameB[15] = "1984",codeUDKB[15]="23481-b";
int nump = 234,yearB=1896;
myBook.setName(nameB).setAuth(auth).setCode(codeUDKB).setNumPages(nump).setYear(yearB);
myBook.print1();
myBook.print2();
return 0;
}
解决方案
这段代码有很多错误:
Autor
并且Book
不完全遵循3/5/0 的规则,因为它们都缺少operator=
赋值运算符,因此对象之间的赋值将浅拷贝字符串成员而不是深拷贝它们,从而导致运行时的双重删除错误。特别是在这种情况下Autor
,这尤其会导致 5 参数的Book()
构造函数和Book::setAuth()
方法出现问题。2 参数
Autor()
构造函数和 5 参数Book()
构造函数没有在其字符串成员中为空终止符分配空间,因此调用strcpy()
将破坏内存。和复制构造函数可以正确处理这个问题Autor()
。Book()
默认值
Autor()
和构造函数使用而不是Book()
分配它们的字符串成员,这将与它们的析构函数不匹配。此外,它们也没有在其字符串成员中为空终止符分配空间。new
new[]
delete[]
默认
Book()
构造函数正在泄漏内存,因为它没有delete[]
在本地分配nameAuth
和字符串。surnameAuth
根本不需要动态分配这些字符串。,
Autor::setName()
,Autor::setSurname()
和方法都在泄漏内存Book::setName()
,Book::setCode()
因为它们没有释放被替换的旧字符串。此外,它们不会为新字符串中的空终止符分配空间。main()
正在提示用户输入,但实际上并未读取用户的输入。
综上所述,尝试更多类似的东西:
#include <iostream>
#include <string.h>
using namespace std;
class Autor {
char* name;
char* surname;
public:
Autor() {
name = new char[2];
strcpy(name, "-");
surname = new char[2];
strcpy(surname, "-");
}
Autor(const char* nam, const char* surnam) {
if (!nam) nam = "-";
if (!surnam) surnam = "-";
name = new char[strlen(nam)+1];
strcpy(name, nam);
surname = new char[strlen(surnam)+1];
strcpy(surname, surnam);
}
Autor(const Autor& a)
{
name = new char[strlen(a.name)+1];
strcpy(name, a.name);
surname = new char[strlen(a.surname)+1];
strcpy(surname, a.surname);
}
~Autor() {
delete[] name;
delete[] surname;
}
Autor& operator=(const Autor& a) {
if (this != &a) {
setName(a.getName());
setSurname(a.getSurname());
}
return *this;
}
const char* getName() const { return name; };
const char* getSurname() const { return surname; };
Autor& setName(const char* nam) {
if (!nam) nam = "-";
char *new_name = new char[strlen(nam)+1];
strcpy(new_name, nam);
delete[] name;
name = new_name;
return *this;
}
Autor& setSurname(const char* surnam) {
if (!surnam) surnam = "-";
char *new_surname = new char[strlen(surnam)+1];
strcpy(new_surname, surnam);
delete[] surname;
surname = new_surname;
return *this;
}
void print1() const {
cout << "First print type: " << name << " " << surname << "\n";
}
void print2() const
{
cout << "Second print type: " << "Author, name: " << name << "\n";
}
};
class Book {
char* name;
char* codeUDK;
Autor auth;
int year;
int numPages;
public:
Book()
: auth("x", "x")
{
name = new char[2];
strcpy(name, "x");
codeUDK = new char[2];
strcpy(codeUDK, "x");
year = 0;
numPages = 0;
}
Book(const char* nam, const char* code, const Autor &a, int yea, int numP)
: auth(a)
{
if (!nam) nam = "x";
if (!code) code = "x";
name = new char[strlen(nam)+1];
strcpy(name, nam);
codeUDK = new char[strlen(code)+1];
strcpy(codeUDK, code);
year = yea;
numPages = numP;
}
Book(const Book& a)
: auth(a.auth)
{
name = new char[strlen(a.name)+1];
strcpy(name, a.name);
codeUDK = new char[strlen(a.codeUDK)+1];
strcpy(codeUDK, a.codeUDK);
year = a.year;
numPages = a.numPages;
}
~Book()
{
delete[] name;
delete[] codeUDK;
}
Book& operator=(const Book& b) {
if (this != &b) {
setName(b.getName());
setCode(b.getCode());
setAutor(b.getAuth());
setYear(b.getYear());
setNumPages(b.getNumPages());
}
return *this;
}
const char* getName() const { return name; }
const char* getCode() const { return codeUDK; }
Autor& getAuth() { return auth; }
const Autor& getAuth() const { return auth; }
int getYear() const { return year; }
int getNumPages() const { return numPages; }
Book& setName(const char* nam)
{
if (!nam) nam = "x";
char *new_name = new char[strlen(nam)+1];
strcpy(new_name, nam);
delete[] name;
name = new_name;
return *this;
}
Book& setCode(const char* code)
{
if (!code) code = "x";
char *new_code = new char[strlen(code)+1];
strcpy(new_code, code);
delete[] codeUDK;
codeUDK = new_code;
return *this;
}
Book& setAuth(const Autor &a)
{
auth = a;
return *this;
}
Book& setYear(int yea)
{
year = yea;
return *this;
}
Book& setNumPages(int num)
{
numPages = num;
return *this;
}
void print1() const {
cout << "First print type: " << name << " code: " << codeUDK << " author's name: " << auth.getName() << " author's surname: " << auth.getSurname() << " year of writing " << year << " amount of pages: " << numPages << "\n";
}
void print2() const {
cout << "Second print type: " << "Book, name and author: " << name << ", Author: " << auth.getName() << auth.getSurname() << "\n";
}
};
int main()
{
char nameA[20], surnameA[20];
cout << "enter name and surname: ";
cin.get(nameA, 20);
cin.get(surnameA, 20);
Autor auth(nameA, surnameA);
Autor auth1(auth);
auth.print1();
auth.print2();
cout << "\ncopied author:\n";
auth1.print1();
auth1.print2();
Book myBook("1984", "23481-b", auth, 1896, 234);
myBook.print1();
myBook.print2();
return 0;
}
话虽这么说,你真的应该使用std::string
而不是char[]
,让编译器为你处理所有的内存管理,例如:
#include <iostream>
#include <string>
using namespace std;
class Autor {
string name;
string surname;
public:
Autor()
: name("-"), surname("-")
{
}
Autor(const string& nam, const string& surnam)
: name(nam), surname(surnam)
{
if (name.empty()) name = "-";
if (surname.empty()) surname = "-";
}
string getName() const { return name; };
string getSurname() const { return surname; };
Autor& setName(const string& nam) {
name = nam;
if (name.empty()) name = "-";
return *this;
}
Autor& setSurname(const char* surnam) {
surname = surnam;
if (surname.empty()) surname = "-";
return *this;
}
void print1() const {
cout << "First print type: " << name << " " << surname << "\n";
}
void print2() const
{
cout << "Second print type: " << "Author, name: " << name << "\n";
}
};
class Book {
string name;
string codeUDK;
Autor auth;
int year;
int numPages;
public:
Book()
: name("x"), codeUDK("x"), auth("x", "x"), year(0), numPages(0)
{
}
Book(const string& nam, const string& code, const Autor &a, int yea, int numP)
: name(nam), codeUDK(code), auth(a), year(yea), numPages(numP)
{
if (name.empty()) name = "x";
if (codeUDK.empty()) codeUDK = "x";
}
string getName() const { return name; }
string getCode() const { return codeUDK; }
Autor& getAuth() { return auth; }
const Autor& getAuth() const { return auth; }
int getYear() const { return year; }
int getNumPages() const { return numPages; }
Book& setName(const string& nam)
{
name = nam;
if (name.empty()) name = "x";
return *this;
}
Book& setCode(const string& code)
{
codeUDK = code;
if (codeUDK.empty()) codeUDK = "x";
return *this;
}
Book& setAuth(const Autor &a)
{
auth = a;
return *this;
}
Book& setYear(int yea)
{
year = yea;
return *this;
}
Book& setNumPages(int num)
{
numPages = num;
return *this;
}
void print1() const {
cout << "First print type: " << name << " code: " << codeUDK << " author's name: " << auth.getName() << " author's surname: " << auth.getSurname() << " year of writing " << year << " amount of pages: " << numPages << "\n";
}
void print2() const {
cout << "Second print type: " << "Book, name and author: " << name << ", Author: " << auth.getName() << auth.getSurname() << "\n";
}
};
int main()
{
string nameA, surnameA;
cout << "enter name and surname: ";
cin >> nameA >> surnameA;
Autor auth(nameA, surnameA);
Autor auth1(auth);
auth.print1();
auth.print2();
cout << "\ncopied author:\n";
auth1.print1();
auth1.print2();
Book myBook("1984", "23481-b", auth, 1896, 234);
myBook.print1();
myBook.print2();
return 0;
}
推荐阅读
- discord.js - Error when I try to make a !ping command in discord.js
- terraform - Terraform 嵌套动态块辅助
- asp.net-core - 引导模式确认 - 删除操作不起作用
- sql - 如何使用基于分区的 INSERT INTO 覆盖表?- 雅典娜
- python - 如何通过处理空格并返回所有匹配项来使用特殊符号拆分字符串?
- nestjs - 无法从 NestJS 中的请求中获取 cookie
- react-native - Native Base - _focus 不改变某些组件样式
- vue.js - Power BI Embeded 无法实时工作
- r - R转换嵌套的for循环_嵌套的并行foreach不起作用
- ruby-on-rails - 如何在 gem CombinePDF 中使用 UTF-8 字体?