2011-02-14 165 views
1

我有上述问题,当我试图设置一个字符串(存储在一个类)等于另一个字符串。我梳理和梳理,试图找出我是否没有初始化任何变量,但我找不到这样的情况。在调试mod中,我得到了上述错误。在发布模式下,它会挂起,Win7会查找问题,不会重大放弃或重试窗口。这里是相关的代码,如果你觉得它应该包括在内,那么在我的主程序中有另一个头文件,我将包含导致错误的行。语言显然是C++。0xC0000005:访问冲突读取位置0xccccccd0。 C++

//Error occurs in this area: 
    Car one; 
    one = two; 
    one.addExtra ("Windows"); 

    log << "Car one: " << one << endl; 
    two = Car(one); // call copy constructor. 
//I realize when I call the first one = two, there are no extras 
//stored int Car one, which is what differs between the two. Remaining 
//code. Extras header: 

#include <iostream> 
#include <string> 
#include <string.h> 
using namespace std; 

class Extras 
{ 
public: 
    friend class Car; 
    friend int main(); 
    friend ostream& operator << (ostream& os, const Extras& in); 
    friend class CarLot; 
    Extras(const Extras& other); 
    Extras& operator=(Extras &rhs); 
    Extras(string in); 
    Extras(); 
    ~Extras(); 
    void modify_ext(string* in); 
    //string ex_list; 
private: 
    int place; 
    string *ex_list; 
}; 
//Extras.cpp: 
#include "Extras.h" 

Extras::Extras(string in) 
{ 
    delete ex_list; 
    ex_list = new string; 
    place = 0; 
    //ex_list = new string[4]; 
    (*ex_list) = in; 
    place++; 
} 

Extras::Extras() 
{ 
    //ex_list = new string[4]; 
    place = 0; 
    //for(int i = 0; i < 4; i++) 
    ex_list = new string; 
    *ex_list = "0"; 
} 

//Overloaded << operator for Extras class to 
//easily output array contents 
ostream& operator<< (ostream& os, Extras const &in) 
{ 
    os << *(in.ex_list); 
    return os; 
} 

Extras& Extras::operator=(Extras &rhs) 
{ 
    if(this != &rhs) 
    { 
     //string temp; 
     //temp = rhs.ex_list; 
     modify_ext(rhs.ex_list); 
     cout << endl << endl << ex_list << endl << endl; 
     place = rhs.place; 
    } 
    return *this; 
} 

Extras::Extras(const Extras& other) : place(other.place), ex_list(other.ex_list) 
{ 
    //for(int i = 0; i < 4; i++) 
     //ex_list = other.ex_list; 
} 

void Extras::modify_ext(string* in) 
{ 
    delete ex_list; 
    ex_list = new string; 
    (*ex_list).resize((*in).size()); 
    for(unsigned int i = 0; i < (*in).size(); i++) 
     ex_list[i] = in[i]; 
} 

Extras::~Extras() 
{ 
    delete ex_list; 
    place = 0; 
} 

//Car Header: 
#include "Extras.h" 

class Car 
{ 
public: 
    friend class Extras; 
    friend Extras& Extras::operator=(Extras &rhs); 
    friend int main(); 
    friend ostream& operator<< (ostream& os, const Car& in); 
    friend class CarLot; 
    friend void add_extra(); 
    ~Car(); 
    Car(); 
    Car(Car& other); 
    Car(string in_name, int in_year, string in_color, float in_cost); 
    Car& operator=(Car const &rhs); 
    void edit_extr(int in); 
    void addExtra(string in); 
private: 
    string name, color; 
    int year, extr_num; 
    float cost; 
    Extras *extr; 
}; 

//Car.cpp: 


#include "car.h" 

//Constructor 
Car::Car(string in_name, int in_year, string in_color, float in_cost) 
{ 
    name = in_name; 
    color = in_color; 
    year = in_year; 
    cost = in_cost; 
    extr = new Extras[3]; 
    extr_num = 0; 
} 

//Overloaded = operator 
Car& Car::operator=(Car const &rhs) 
{ 
    if(this != &rhs) 
    { 
     name = rhs.name; 
     color = rhs.color; 
     year = rhs.year; 
     cost = rhs.cost; 
     //delete extr; 
     extr = rhs.extr; 
     extr_num = rhs.extr_num; 
    } 
    return *this; 

} 



//Default Constructor 
Car::Car() 
{ 
    name = "TEMP"; 
    color = "BLUE"; 
    year = 0; 
    cost = 0; 
    extr = new Extras[3]; 
    extr_num = 0; 
} 

//Destructor 
Car::~Car() 
{ 
    delete extr; 
    extr = NULL; 
} 

//Copy constructor 
Car::Car(Car& other) : name(other.name), color(other.color), year(other.year), 
    cost(other.cost), extr_num(other.extr_num) 

{ 
    //delete extr; 
    for(int i = 0; i < extr_num; i++) 
    { 
     extr[i].modify_ext(other.extr[i].ex_list); 
     extr[i].place = other.extr[i].place; 
    } 
} 





//Overloaded << operator for Car class 
ostream& operator<< (ostream& os, const Car& in) 
{ 
    os.precision(2); 
    os << in.name << ", " << in.year << ", " 
     << in.color << ", $"<< in.cost << ", "; 
    os << "extras include: "; 
    for(int k = 0; k < in.extr_num; k++) 
    { 
     os << in.extr[k] << ", "; 
    } 
    os << endl; 
    return os; 
} 

void Car::edit_extr(int in) 
{ 
    Extras* temp; 
    temp = new Extras[in]; 
    for(int i = 0; i < in; i++) 
     temp[i] = extr[i]; 
    extr_num = in; 
    delete extr; 
    extr = temp; 
} 

void Car::addExtra(string in) 
{ 
    if(extr_num == 3) 
    { 
     //log << "Car has too many extras."; 
     return; 
    } 
    //edit_extr(extr_num + 1); 
    *(extr[extr_num].ex_list) = in; 
    extr[extr_num].place++; 
    extr_num++; 
} 

正如我所说的,我多了一个额外的头,另一个类,并且主程序如果这些需要被包括在内,但我想这是绰绰有余码以上(对不起!)的人通过看。任何帮助将不胜感激。

+4

您应该总是尝试*最小化*重现问题所需的代码。至少尝试在调试器下运行它。 – 2011-02-14 19:20:26

+1

我不认为这个问题值得任何答案... – 2011-02-14 19:54:12

+0

Piotr,我做了这两个。我在我的OP中说过,我在调试中运行它,并且我是如何得到错误是问题的标题,并且我试图单独测试每个函数并且没有得到结果。之后我开始重新添加东西。抱歉。 – zmarine 2011-02-14 21:16:34

回答

8

我所看到的那个地方不对头:


two = Car(one); // call copy constructor. 

不,它创建了拷贝构造一个临时对象,通过这operator=()two,然后破坏了暂时的。


Extras& operator=(Extras &rhs); 

应该是:

Extras& operator=(const Extras &rhs); 

Extras::Extras(string in) 
{ 
    delete ex_list; 
    ex_list = new string; 
    place = 0; 
    //ex_list = new string[4]; 
    (*ex_list) = in; 
    place++; 
} 

更好:

Extras::Extras(const string& in): place(1), ex_list(new string(in)) 
{ 
} 

Extras::Extras(const Extras& other) : place(other.place), ex_list(other.ex_list) 
{ 
    //for(int i = 0; i < 4; i++) 
     //ex_list = other.ex_list; 
} 

看看您的默认构造函数,显然Extras对象拥有ex_list中的字符串。但是,此复制构造函数声明原始对象的所有权为ex_list。它应使自己的副本:

Extras::Extras(const Extras& other): place(other.place), 
    ex_list(new string(other.ex_list)) 
{ 
} 

void Extras::modify_ext(string* in) 
{ 
    delete ex_list; 
    ex_list = new string; 
    (*ex_list).resize((*in).size()); 
    for(unsigned int i = 0; i < (*in).size(); i++) 
     ex_list[i] = in[i]; 
} 

你复制的字符串。所有你需要的是:

void Extras::modify_ext(const string* in) 
{ 
    *ex_list = *in; 
} 

移动到Car ...

friend class Extras; 
friend Extras& Extras::operator=(Extras &rhs); 
friend int main(); 
friend ostream& operator<< (ostream& os, const Car& in); 
friend class CarLot; 
friend void add_extra(); 

你应该考虑重构代码,以摆脱这些。


Car(Car& other); 
Car(string in_name, int in_year, string in_color, float in_cost); 

应该是:传递对象的功能时

Car(const Car& other); 
Car(const string& in_name, int in_year, const string& in_color, float in_cost); 

引用是你的朋友。


我打算在这里停下来。

5

在您的构造函数中,您正在删除ex_list。它还没有分配,所以这是错误的。删除它,并在分配新字符串时执行此操作:

ex_list = new string(in); 

这样你就可以使用字符串拷贝构造函数。你可以在构造函数中删除你正在尝试做的其他任何事情,因为这会为你做。

编辑:

其实,还有所有在本代码一吨的问题。有没有什么理由让你的字符串在内部成为一个指针?您在一堆不同的地方没有正确使用指针。当我向下滚动时,我只注意到第一个。

2

调试版本中的分配器使用VC++使用一些魔术值来填充分配的区域。特别是,0xCC是已分配的内存,但现在已释放。因此,地址0xCCCCCCD0看起来像一个小的偏移量(例如,一个结构或类成员)从内存中的指针释放。鉴于此,Mark Loeser的回答看起来很有希望。

相关问题