cout 打印后崩溃 object getter
crashing after cout prints object getter
基本上我的代码崩溃了,我找不到原因,我使用了 Code::Blocks 调试器但对我没有帮助。它在打印出属性 [4] 的正确数据后崩溃。我知道这不是执行此操作的最佳方法,但它适用于 class,我需要在其中展示可以完成的多种方法。我的问题是在显示 "River Kwai Restaurant" 后它崩溃了,无法弄清楚为什么。
const int MAX_PROPERTIES = 5;
int main(void) {
Property properties[MAX_PROPERTIES];
Rentals tempRent;
tempRent = Rentals();
tempRent.setBond(10000);
tempRent.setMonthlyRent(700);
tempRent.setOwner("River Kwai Restaurant");
tempRent.setAddress("3 Bishopton Road");
tempRent.setSuburb("Footscray");
tempRent.setPostcode(5000);
properties[4] = tempRent;
tempRent.~Rentals();
cout << properties[4].getOwner() << endl;
return 0;
}
Property::Property(){
owner = "NULL";
address = "NULL";
suburb = "NULL";
postcode = 0;
}
Property::Property(string theOwner, string theAddress,
string theSuburb, int thepostCode):
owner(theOwner), address(theAddress),
suburb(theSuburb), postcode(thepostCode){}
Property::~Property() {}
Rentals::Rentals(string theOwner, string theAddress, string theSuburb,
int thePostCode, double theBond, double theMonthlyRent):
Property(theOwner, theAddress, theSuburb, thePostCode),
bond(theBond), monthlyRent(theMonthlyRent){}
Rentals::Rentals() : Property() {
owner = "NULL";
address = "NULL";
suburb = "NULL";
postcode = 0;
bond = 0;
monthlyRent = 0;
}
Rentals::~Rentals() {}
注意:删除析构函数确实可以解决问题,但我想知道为什么?析构函数是否应该完全不影响属性[4],因为它已经初始化了?
这是相关代码,但如果需要,我会 post 整个代码/header 文件。
#include "property_a.h"
#include "rentals.h"
#include "commercial.h"
#include "sales.h"
const int MAX_PROPERTIES = 5;
int main(void) {
Property properties[MAX_PROPERTIES];
Rentals tempRent;
properties[0] = Commercial("Notting Hill McDonalds",
"4 Gardiner Road", "Notting Hill", 5000,
"Li3000");
properties[1] = Rentals("Janet Dalgleish", "30 Firhill Court",
"Mary Hill", 4000, 500.00, 300.00);
properties[2] = Sales("Robert Burns", "3 Ayr Court", "Irvine", 4000,
"10/10/2015", 700000);
properties[3] = Property();
properties[3] = properties[0];
tempRent = Rentals();
tempRent.setBond(10000);
tempRent.setMonthlyRent(700);
tempRent.setOwner("River Kwai Restaurant");
tempRent.setAddress("3 Bishopton Road");
tempRent.setSuburb("Footscray");
tempRent.setPostcode(5000);
properties[4] = tempRent;
cout << properties[4].getOwner() << endl;
return 0;
}
Property::Property(){
owner = "NULL";
address = "NULL";
suburb = "NULL";
postcode = 0;
}
Property::Property(string theOwner, string theAddress,
string theSuburb, int thepostCode):
owner(theOwner), address(theAddress),
suburb(theSuburb), postcode(thepostCode){}
Property::~Property() {}
Commercial::Commercial() : Property() {
owner = "NULL";
address = "NULL";
suburb = "NULL";
postcode = 0;
license = "NULL";
}
Commercial::Commercial(string theOwner, string theAddress,
string theSuburb, int thepostCode,
string theLicense): Property(theOwner, theAddress,
theSuburb, thepostCode), license(theLicense) {}
Commercial::~Commercial() {}
Rentals::Rentals(string theOwner, string theAddress, string theSuburb,
int thePostCode, double theBond, double theMonthlyRent):
Property(theOwner, theAddress, theSuburb, thePostCode),
bond(theBond), monthlyRent(theMonthlyRent){}
Rentals::Rentals() : Property() {
owner = "NULL";
address = "NULL";
suburb = "NULL";
postcode = 0;
bond = 0;
monthlyRent = 0;
}
Rentals::~Rentals() {}
Sales::Sales(string theOwner, string theAddress, string theSuburb,
int thepostCode, string theAuctionDate, double thePrice):
Property(theOwner, theAddress, theSuburb, thepostCode),
auctionDate(theAuctionDate), price(thePrice) {}
Sales::Sales() : Property() {
owner = "NULL";
address = "NULL";
suburb = "NULL";
postcode = 0;
auctionDate = "NULL";
price = 0;
}
Sales::~Sales() {}
属性 header
#ifndef __PROPERTY_A_H__
#define __PROPERTY_A_H__
/*TODO REQUIRED HEADER FILES AND NAMESPACES*/
#include <string>
#include "utility1.h"
class Property
{
protected:
string owner;
string address;
string suburb;
int postcode;
public:
Property();
Property(string theOwner, string theAddress, string theSuburb, int thepostCode);
virtual ~Property();
string getOwner() const {return owner;}; //Note the use of const
string getAddress() const {return address;};
string getSuburb() const {return suburb;};
int getPostcode() const {return postcode;};
void setOwner(string newOwner) {owner = newOwner;};
void setAddress(string newAddress) {address = newAddress;};
void setSuburb( string newSuburb) {suburb = newSuburb;};
void setPostcode(int newPostcode) {postcode = newPostcode;};
};
#endif
租金header
#ifndef __RENTALS_H__
#define __RENTALS_H__
#include "property_a.h"
class Rentals : public Property
{
protected:
double bond;
double monthlyRent;
public:
Rentals();
Rentals(string theOwner, string theAddress, string theSuburb,
int thepostCode, double theBond, double theMonthlyRent);
~Rentals() ;
double getBond() const {return bond;}; //Note the use of const
void setBond(double theBond) {bond = theBond;};
double getMonthlyRent() const {return monthlyRent;}; //Note the use of const
void setMonthlyRent(double theMonthlyRent) {monthlyRent = theMonthlyRent;};
};
#endif
另一位评论者建议您查找 object slicing. 这确实描述了问题,但您可以通过在代码中添加一些调试语句来更具体地看到它:
std::cout << "Size of properties: " << sizeof(properties) << std::endl;
std::cout << "Size of properties[4]: " << sizeof(properties[4]) <<std::endl;
std::cout << "Size of tmpRent: "<< sizeof(tempRent) <<std::endl;
输出如下所示:
Size of properties: 440
Size of properties[4]: 88
Size of tmpRent: 104
看起来一个属性元素不够大,无法容纳您的子类的一个元素...这是怎么回事?
当您声明 Properties properties[5]
时,您是在声明一个 Properties 类型的对象数组,它分配一个连续的内存块。您实际上可以通过打印地址看到:
std::cout << "Start of properties: " << &properties <<std::endl;
std::cout << "Address of properties[0]: " << &properties[0] << std::endl;
std::cout << "Address of properties[1]: " << &properties[1] << std::endl;
std::cout << "Address of properties[2]: " << &properties[2] << std::endl;
std::cout << "Address of properties[3]: " << &properties[3] << std::endl;
std::cout << "Address of properties[4]: " << &properties[4] << std::endl;
在我的机器上我得到:
Start of properties: 0x7fff5a4c6070
Address of properties[0]: 0x7fff5a4c6070
Address of properties[1]: 0x7fff5a4c60c8
Address of properties[2]: 0x7fff5a4c6120
Address of properties[3]: 0x7fff5a4c6178
Address of properties[4]: 0x7fff5a4c61d0
这些数字很大,但您可以看到数组中每个元素的地址增加了 0x58 或 88 字节。当您分配给 properties[4] 时,C++ 将 properties[4] 视为指针,并将 104 个字节复制到它指向的位置。赋值 properties[4] = tempRent 等同于 memcpy(&tempRent, &properties[4], 104)
。 C++ 只是假设你有足够的内存来保存对象(104 字节)。但是直到内存块的末尾只剩下 88 个字节。你的任务是覆盖数组的末尾并破坏下一段内存。该程序可能随时崩溃,它可能显示损坏的数据,或者它可能看起来工作得很好(就像我 运行 它在我的 Mac 上一样。)
基本上我的代码崩溃了,我找不到原因,我使用了 Code::Blocks 调试器但对我没有帮助。它在打印出属性 [4] 的正确数据后崩溃。我知道这不是执行此操作的最佳方法,但它适用于 class,我需要在其中展示可以完成的多种方法。我的问题是在显示 "River Kwai Restaurant" 后它崩溃了,无法弄清楚为什么。
const int MAX_PROPERTIES = 5;
int main(void) {
Property properties[MAX_PROPERTIES];
Rentals tempRent;
tempRent = Rentals();
tempRent.setBond(10000);
tempRent.setMonthlyRent(700);
tempRent.setOwner("River Kwai Restaurant");
tempRent.setAddress("3 Bishopton Road");
tempRent.setSuburb("Footscray");
tempRent.setPostcode(5000);
properties[4] = tempRent;
tempRent.~Rentals();
cout << properties[4].getOwner() << endl;
return 0;
}
Property::Property(){
owner = "NULL";
address = "NULL";
suburb = "NULL";
postcode = 0;
}
Property::Property(string theOwner, string theAddress,
string theSuburb, int thepostCode):
owner(theOwner), address(theAddress),
suburb(theSuburb), postcode(thepostCode){}
Property::~Property() {}
Rentals::Rentals(string theOwner, string theAddress, string theSuburb,
int thePostCode, double theBond, double theMonthlyRent):
Property(theOwner, theAddress, theSuburb, thePostCode),
bond(theBond), monthlyRent(theMonthlyRent){}
Rentals::Rentals() : Property() {
owner = "NULL";
address = "NULL";
suburb = "NULL";
postcode = 0;
bond = 0;
monthlyRent = 0;
}
Rentals::~Rentals() {}
注意:删除析构函数确实可以解决问题,但我想知道为什么?析构函数是否应该完全不影响属性[4],因为它已经初始化了?
这是相关代码,但如果需要,我会 post 整个代码/header 文件。
#include "property_a.h"
#include "rentals.h"
#include "commercial.h"
#include "sales.h"
const int MAX_PROPERTIES = 5;
int main(void) {
Property properties[MAX_PROPERTIES];
Rentals tempRent;
properties[0] = Commercial("Notting Hill McDonalds",
"4 Gardiner Road", "Notting Hill", 5000,
"Li3000");
properties[1] = Rentals("Janet Dalgleish", "30 Firhill Court",
"Mary Hill", 4000, 500.00, 300.00);
properties[2] = Sales("Robert Burns", "3 Ayr Court", "Irvine", 4000,
"10/10/2015", 700000);
properties[3] = Property();
properties[3] = properties[0];
tempRent = Rentals();
tempRent.setBond(10000);
tempRent.setMonthlyRent(700);
tempRent.setOwner("River Kwai Restaurant");
tempRent.setAddress("3 Bishopton Road");
tempRent.setSuburb("Footscray");
tempRent.setPostcode(5000);
properties[4] = tempRent;
cout << properties[4].getOwner() << endl;
return 0;
}
Property::Property(){
owner = "NULL";
address = "NULL";
suburb = "NULL";
postcode = 0;
}
Property::Property(string theOwner, string theAddress,
string theSuburb, int thepostCode):
owner(theOwner), address(theAddress),
suburb(theSuburb), postcode(thepostCode){}
Property::~Property() {}
Commercial::Commercial() : Property() {
owner = "NULL";
address = "NULL";
suburb = "NULL";
postcode = 0;
license = "NULL";
}
Commercial::Commercial(string theOwner, string theAddress,
string theSuburb, int thepostCode,
string theLicense): Property(theOwner, theAddress,
theSuburb, thepostCode), license(theLicense) {}
Commercial::~Commercial() {}
Rentals::Rentals(string theOwner, string theAddress, string theSuburb,
int thePostCode, double theBond, double theMonthlyRent):
Property(theOwner, theAddress, theSuburb, thePostCode),
bond(theBond), monthlyRent(theMonthlyRent){}
Rentals::Rentals() : Property() {
owner = "NULL";
address = "NULL";
suburb = "NULL";
postcode = 0;
bond = 0;
monthlyRent = 0;
}
Rentals::~Rentals() {}
Sales::Sales(string theOwner, string theAddress, string theSuburb,
int thepostCode, string theAuctionDate, double thePrice):
Property(theOwner, theAddress, theSuburb, thepostCode),
auctionDate(theAuctionDate), price(thePrice) {}
Sales::Sales() : Property() {
owner = "NULL";
address = "NULL";
suburb = "NULL";
postcode = 0;
auctionDate = "NULL";
price = 0;
}
Sales::~Sales() {}
属性 header
#ifndef __PROPERTY_A_H__
#define __PROPERTY_A_H__
/*TODO REQUIRED HEADER FILES AND NAMESPACES*/
#include <string>
#include "utility1.h"
class Property
{
protected:
string owner;
string address;
string suburb;
int postcode;
public:
Property();
Property(string theOwner, string theAddress, string theSuburb, int thepostCode);
virtual ~Property();
string getOwner() const {return owner;}; //Note the use of const
string getAddress() const {return address;};
string getSuburb() const {return suburb;};
int getPostcode() const {return postcode;};
void setOwner(string newOwner) {owner = newOwner;};
void setAddress(string newAddress) {address = newAddress;};
void setSuburb( string newSuburb) {suburb = newSuburb;};
void setPostcode(int newPostcode) {postcode = newPostcode;};
};
#endif
租金header
#ifndef __RENTALS_H__
#define __RENTALS_H__
#include "property_a.h"
class Rentals : public Property
{
protected:
double bond;
double monthlyRent;
public:
Rentals();
Rentals(string theOwner, string theAddress, string theSuburb,
int thepostCode, double theBond, double theMonthlyRent);
~Rentals() ;
double getBond() const {return bond;}; //Note the use of const
void setBond(double theBond) {bond = theBond;};
double getMonthlyRent() const {return monthlyRent;}; //Note the use of const
void setMonthlyRent(double theMonthlyRent) {monthlyRent = theMonthlyRent;};
};
#endif
另一位评论者建议您查找 object slicing. 这确实描述了问题,但您可以通过在代码中添加一些调试语句来更具体地看到它:
std::cout << "Size of properties: " << sizeof(properties) << std::endl;
std::cout << "Size of properties[4]: " << sizeof(properties[4]) <<std::endl;
std::cout << "Size of tmpRent: "<< sizeof(tempRent) <<std::endl;
输出如下所示:
Size of properties: 440
Size of properties[4]: 88
Size of tmpRent: 104
看起来一个属性元素不够大,无法容纳您的子类的一个元素...这是怎么回事?
当您声明 Properties properties[5]
时,您是在声明一个 Properties 类型的对象数组,它分配一个连续的内存块。您实际上可以通过打印地址看到:
std::cout << "Start of properties: " << &properties <<std::endl;
std::cout << "Address of properties[0]: " << &properties[0] << std::endl;
std::cout << "Address of properties[1]: " << &properties[1] << std::endl;
std::cout << "Address of properties[2]: " << &properties[2] << std::endl;
std::cout << "Address of properties[3]: " << &properties[3] << std::endl;
std::cout << "Address of properties[4]: " << &properties[4] << std::endl;
在我的机器上我得到:
Start of properties: 0x7fff5a4c6070
Address of properties[0]: 0x7fff5a4c6070
Address of properties[1]: 0x7fff5a4c60c8
Address of properties[2]: 0x7fff5a4c6120
Address of properties[3]: 0x7fff5a4c6178
Address of properties[4]: 0x7fff5a4c61d0
这些数字很大,但您可以看到数组中每个元素的地址增加了 0x58 或 88 字节。当您分配给 properties[4] 时,C++ 将 properties[4] 视为指针,并将 104 个字节复制到它指向的位置。赋值 properties[4] = tempRent 等同于 memcpy(&tempRent, &properties[4], 104)
。 C++ 只是假设你有足够的内存来保存对象(104 字节)。但是直到内存块的末尾只剩下 88 个字节。你的任务是覆盖数组的末尾并破坏下一段内存。该程序可能随时崩溃,它可能显示损坏的数据,或者它可能看起来工作得很好(就像我 运行 它在我的 Mac 上一样。)