0xC0000005:访问冲突读取位置0xccccccd0。 C ++

时间:2011-02-14 19:10:53

标签: c++ access-violation

当我尝试将字符串(存储在类中)设置为等于另一个字符串时,我遇到了上述问题。我已经梳理和梳理试图找到我是否没有初始化任何变量,但我找不到这样的情况。在debug mod中,我得到了上述错误。在发布模式下,它会挂起,Win7会查找问题,没有重大中止或重试窗口。这是相关的代码,如果你认为应该包含我的主程序,还有另一个头文件,我将包括导致错误的行。语言显然是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++;
}

正如我所说,我还有一个额外的标题,另一个类和一个主程序,如果需要包含它们,但我认为这是足够的代码(对不起!)供任何人查看。任何帮助都会非常感激。

3 个答案:

答案 0 :(得分: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);

将对象传递给函数时,引用是你的朋友。


我要到此为止。

答案 1 :(得分:5)

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

ex_list = new string(in);

这样您就可以使用字符串复制构造函数。您可以在构造函数中删除下面尝试执行的任何操作,因为这样可以为您完成。

编辑:

实际上,这段代码中存在大量问题。你有什么理由希望你的字符串在内部成为指针吗?您没有在一堆不同的地方正确使用指针。当我向下滚动时,我才注意到第一个。

答案 2 :(得分:2)

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