我收到核心转储错误(内存泄漏),我不知道它来自哪里。我试图一次运行程序部分并最小化问题。任何帮助,将不胜感激。谢谢
基本标题文件。
#ifndef VEHICLE_H
#define VEHICLE_H
#include <iostream>
#include <string>
using namespace std;
class Vehicle{
protected:
char *name;
static ostream *out ;
public:
Vehicle();
Vehicle(string &n);
Vehicle (const Vehicle & b);
~Vehicle();
Vehicle& operator =(const Vehicle &b);
virtual void print(void) = 0;
virtual void read(void) = 0;
};
基础构造函数
#include "vehicle.h"
#include <iostream>
#include <cstring>
ostream * Vehicle :: out = &cout;
Vehicle :: Vehicle(){
name = new char;
strcpy(name, "");
}
Vehicle :: Vehicle(string &n){
int len = n.length()+ 1;
delete [] name;
name = new char[len];
strcpy(name,n.c_str());
}
Vehicle :: Vehicle(const Vehicle & v){
int len = strlen(v.name)+ 1;
delete [] name;
name = new char[len];
strcpy(name,v.name);
}
Vehicle & Vehicle::operator = (const Vehicle &b){
if(this == &b){
return *this;
}
int len = strlen(b.name)+ 1;
delete [] name;
name = new char[len];
strcpy(name,b.name);
return *this;
}
Vehicle:: ~Vehicle(){
delete [] name;
}
派生的头文件
#ifndef MOTORVEHICLE_H
#define MOTORVEHICLE_H
#include <cstring>
#include "vehicle.h"
class MotorVehicle: public Vehicle{
protected:
string make;
string model;
double mpg;
public:
MotorVehicle();
MotorVehicle (const string &n,const string &m = "",const string &md = "", const double &mp = 0.0);
//accessor functions
string getName()const;
string getMake()const;
string getModel()const;
double getMpg()const;
ostream & getOut();
//mutator functions
string setName();
void setMake();
void setModel();
void setMpg();
void setOut(ostream & o);
//virtual functions
void print();
void read();
};
#endif // MOTORVEHICLE_H
MotorVehicle实施。这是错误发生的地方。
#include "motorVehicle.h"
#include <string>
#include <iostream>
MotorVehicle:: MotorVehicle(): Vehicle(), make(""), model(""), mpg(0.0){
make = "";
model = "";
mpg = 0.0;
}
MotorVehicle :: MotorVehicle(const string &n, const string &m, const string &md, const double &mp){
int len = n.length()+ 1;
delete [] name;
name = new char[len];
strcpy(name,n.c_str());
make = m;
model = md;
mpg = mp;
}
//accessor functions
string MotorVehicle :: getName()const{
string temp(name);
return temp;
}
string MotorVehicle :: getMake()const {
return make;
}
string MotorVehicle :: getModel()const {
return model;
}
double MotorVehicle :: getMpg()const {
return mpg;
}
ostream & MotorVehicle :: getOut(){
return *out;
}
//mutator functions
string MotorVehicle :: setName(){
cerr << "dododd" <<endl;
string nm1;
cin >> nm1;
int len = nm1.length()+ 1;
delete [] name;
name = new char[len];
strcpy(name,nm1.c_str());
}
void MotorVehicle :: setMake(){
cin >> make;
}
void MotorVehicle :: setModel(){
cin >> model;
}
void MotorVehicle :: setMpg(){
cin >> mpg;
}
void MotorVehicle :: setOut(ostream & o){
out = &o;
}
//virtual function
void MotorVehicle :: print(){
*out << name << make << model << mpg <<" ";
}
void MotorVehicle :: read(){
*out << "Please enter name for this Vehicle: " << endl;
setName();
*out << "Please enter make for this Vehicle: " << endl;
setMake();
*out << "Please enter model for this Vehicle: " << endl;
setModel();
*out << "Please enter miles per gallon for this Vehicle: " << endl;
setMpg();
}
卡车标题
#ifndef TRUCK_H
#define TRUCK_H
#include "motorVehicle.h"
class Truck: public MotorVehicle{
protected:
double cargoCapacity;
public:
Truck();
Truck (string &n,string &m,string &md, double &mp , double &cp);
//accessor functions
double getcargoCapacity()const;
//mutator functions
void setcargoCapacity();
//virtual functions
void print();
void read();
};
#endif
卡车实施
#include "truck.h"
Truck :: Truck() : MotorVehicle(){
cargoCapacity = 0.0;
}
Truck :: Truck(string &n, string &m, string &md, double &mp, double &cp ): MotorVehicle (n,m,md,mp){
cargoCapacity = 0.0;
}
double Truck :: getcargoCapacity()const{
return cargoCapacity;
}
void Truck :: setcargoCapacity(){
cin >> cargoCapacity;
}
void Truck :: print(){
*out << name << make << model << mpg << cargoCapacity << " ";
}
void Truck :: read(){
*out << "Please enter cargo capacity for this Vehicle: " << endl;
setcargoCapacity();
*out << "Please enter name for this Vehicle: " << endl;
setName();
*out << "Please enter make for this Vehicle: " << endl;
setMake();
*out << "Please enter model for this Vehicle: " << endl;
setModel();
*out << "Please enter MPG for this Vehicle: " << endl;
setMpg();
}
车头
#ifndef CAR_H
#define CAR_H
#include "motorVehicle.h"
class Car: public MotorVehicle{
private:
string trim;
public:
Car();
Car (string &n,string &m,string &md,double &mp, string &t);
//accessor functions
string getTrim()const;
//mutator functions
void setTrim();
//virtual functions
void print();
void read();
};
#endif // CAR_H
汽车实施
#include "car.h"
Car :: Car (){
MotorVehicle();
}
Car :: Car(string &n, string &m, string &md, double &mp, string &t) : MotorVehicle (n,m,md,mp){
trim = "";
}
string Car :: getTrim()const{
return trim;
}
void Car :: setTrim(){
cin >> trim;
}
void Car :: print(){
*out << name << make << model << mpg << trim << " ";
}
void Car :: read (){
*out << "Please enter trim for this Vehicle: " << endl;
setTrim();
*out << "Please enter name for this Vehicle: " << endl;
setName();
*out << "Please enter make for this Vehicle: " << endl;
setMake();
*out << "Please enter model for this Vehicle: " << endl;
setModel();
*out << "Please enter MPG for this Vehicle: " << endl;
setMpg();
}
主要
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <typeinfo>
#include "motorVehicle.h"
// car.h & truck.h included twice to test #ifndef #define ... #endif structure
#include "car.h"
#include "car.h"
#include "truck.h"
#include "truck.h"
typedef vector<MotorVehicle *> vectorOfMotorVehicle;
using namespace std;
// prompt the user for the Vehicle type to create, and get the reply
string prompt(void);
int main() {
vectorOfMotorVehicle v; // store dynamically created MotorVehicles
// or objects derived from MotorVehicles
int numVehicles = 0; // denotes how many MotorVehicles we have
string reply; // indicates type of MotorVehicle to build
bool error = false; // set when a user response is in error
string outputLocation; // where the output of print() will go
ofstream *out = NULL;
MotorVehicle *m;
// uncomment following line to test that Vehicle is an abstract base class
// Vehicle theVehicle;
// push a Vehicle into the vector so first "real" Vehicle is at position 1
m = new MotorVehicle("None");
v.push_back(m);
// chose where the output will go
cout << "Where would you like the output? ";
cin >> outputLocation;
if (outputLocation == "stdout") {
; // no action to take, because stdout (i.e., cout) is the default
} else if (outputLocation == "stderr") {
v[0]->setOut(cerr);
} else {
out = new ofstream;
out->open(outputLocation.c_str());
if (out->fail()) {
cerr << "Error: error writing to " << outputLocation << endl;
return 1;
}
v[0]->setOut(*out);
}
// get the type of Vehicle to create
reply = prompt();
// loop, reading vehicle descriptions, until a "quit" command is received
while (reply != "quit") {
// create the new MotorVehicle object and push it into the vector
switch (toupper(reply[0])) {
case 'T' : m = (MotorVehicle *) (new Truck);
v.push_back(m);
break;
case 'C' : m = (MotorVehicle *) (new Car);
v.push_back(m);
break;
case 'Q' : reply = "quit";
continue;
default : cerr << "Incorrect response\n\n";
error = true;
}
// if no error, then we have a new Vehicle to initialize via read()
if (!error) {
numVehicles++;
v[numVehicles]->read();
}
// reset error flag, and request a new Vehicle type
error = false;
reply = prompt();
}
// report on what Vehicles were created to test read() and print()
for (int i = 0; i <= numVehicles; i++) {
//*out << "Vehicle " << i << endl;
// print the Vehicle characteristics (attributes)
v[i]->print();
//*out << endl;
// free the storage for this Vehicle
delete v[i];
}
// if we opened an output file, then close it
if (out != NULL) {
out->close();
delete out;
}
return 0;
}
// prompt the user for the Vehicle type to create, and get the reply
string prompt() {
string reply; // the user reponse to the prompt
// prompt for and get user response
cout << "\nWhich type of vehicle would you like to initialize"
<< "\n--car or truck (or \"quit\" to exit): ";
cin >> reply;
return reply;
}
当派生类尝试调用setName函数时,它会继续抛出核心转储。泄漏来自哪里?
谢谢
答案 0 :(得分:0)
不是100%确定车辆结构中名称分配的有效性,但它很可能是NULL。当您尝试删除[] NULL时,这将是 setName 的问题。
所以改变
Vehicle :: Vehicle(){
name = '\0';
}
到
Vehicle :: Vehicle(){
name = new char[1];
name[0] = '\0';
}
你应该拥有该内存的实际所有权以便删除。记得在desctrutor处释放已分配的内存。