访问冲突读取位置VS2015

时间:2016-12-15 10:08:31

标签: c++

首先是我的代码 http://ideone.com/qckStZ

#include<stdio.h>
#include<cstring>
#include<utility>
using namespace std;
#define nameLength 50
// all 'Rate' attribute appear to be in '%' unit
//exaple: fatRate=70 which mean fatRate is 70%
class ingredient
{
private:
    friend class mix_ingredient;
    char* name;
    unsigned weigh;
    unsigned fatWeigh;
    unsigned glutenWeigh;
    unsigned condenceRate;
public:
    virtual unsigned getWeigh() { return weigh; }
    virtual unsigned getFatWeigh() { return fatWeigh; }
    virtual unsigned getGlutenWeigh() { return glutenWeigh; }
    virtual unsigned getCondenceRate() { return condenceRate; }
public:
    //virtual void ini() = 0;
public:
    ingredient() { name = new char[nameLength]; }
    ingredient(const ingredient& x) :name(new char[nameLength])
    {
        strcpy(name, x.name);
        weigh = x.weigh;
        fatWeigh = x.fatWeigh;
        glutenWeigh = x.glutenWeigh;
        condenceRate = x.condenceRate;
    }
    ingredient(ingredient&& x)noexcept: name(new char[nameLength])
    {
        strcpy(name, x.name);
        weigh = x.weigh;
        fatWeigh = x.fatWeigh;
        glutenWeigh = x.glutenWeigh;
        condenceRate = x.condenceRate;
        x.name = NULL;
    }
    virtual ingredient& operator=(const ingredient& x)
    {
        ingredient tmp(x);
        *this = std::move(tmp);
        return *this;
    }
    ingredient& operator=(ingredient&& x)noexcept
    {
        name = x.name;
        x.name = NULL;
        weigh = x.weigh;
        fatWeigh = x.fatWeigh;
        glutenWeigh = x.glutenWeigh;
        condenceRate = x.condenceRate;
        return *this;
    }
    ~ingredient()
    {
        delete[] name;
    }
};
typedef class raw_ingredient: public ingredient
{
private:
    char* name;
    unsigned weigh;
    unsigned fatRate;
    unsigned glutenRate;
    unsigned condenceRate;
public:
    virtual unsigned getFatWeigh() { return fatRate*(weigh * 5)*condenceRate / 1000000; }
    virtual unsigned getGlutenWeigh() { return glutenRate*weigh * 30 / 10000; }
    virtual unsigned getWeigh() { return weigh; }
    virtual unsigned getFatRate() { return fatRate; }
    virtual unsigned getGlutenRate() { return glutenRate; }
    virtual unsigned getCondenceRate() { return condenceRate; }
public:

public:
    raw_ingredient() { name = new char[nameLength]; }
    raw_ingredient(const char* name, unsigned w, unsigned fR, unsigned gR, unsigned cR)
    {
        this->name = new char[nameLength];
        strcpy(this->name, name);
        weigh = w;
        fatRate = fR;
        glutenRate = gR;
        condenceRate = cR;
    }
    raw_ingredient(const raw_ingredient& x) :name(new char[nameLength])
    {
        strcpy(name, x.name);
        weigh = x.weigh;
        fatRate = x.fatRate;
        glutenRate = x.glutenRate;
        condenceRate = x.condenceRate;
    }
    raw_ingredient(raw_ingredient&& x)noexcept: name(new char[nameLength])
    {
        strcpy(name, x.name);
        weigh = x.weigh;
        fatRate = x.fatRate;
        glutenRate = x.glutenRate;
        condenceRate = x.condenceRate;
        x.name = NULL;
    }
    virtual raw_ingredient& operator=(const raw_ingredient& x)
    {
        raw_ingredient tmp(x);
        *this = std::move(tmp);
        return *this;
    }
    raw_ingredient& operator=(raw_ingredient&& x)noexcept
    {
        name = x.name;
        x.name = NULL;
        weigh = x.weigh;
        fatRate = x.fatRate;
        glutenRate = x.glutenRate;
        condenceRate = x.condenceRate;
        return *this;
    }
    ~raw_ingredient()
    {
        delete[] name;
    }

}raw;
typedef class mix_ingredient: public ingredient
{
private:
    ingredient** ingre;
    unsigned n = 0;//Number of ingredient // 0 mean empty

public:
    void ini();
    int put(ingredient* x);
public:
    virtual unsigned getWeigh() { return weigh; }
    virtual unsigned getFatWeigh() { return fatWeigh; }
    virtual unsigned getGlutenWeigh() { return glutenWeigh; }
    virtual unsigned getCondenceRate() { return condenceRate; }
public:
    mix_ingredient(int n) { ingre = new ingredient*[n]; this->n = n; }
    mix_ingredient(ingredient* x) : ingre(new ingredient*), n(1)
    {
        ingre = &x;
    }
    mix_ingredient(const mix_ingredient& x) :ingre(new ingredient*[n])
    {
        for (int i = 0;i < n;i++)
            ingre[i] = x.ingre[i];
        weigh = x.weigh;
        fatWeigh = x.fatWeigh;
        glutenWeigh = x.glutenWeigh;
        condenceRate = x.condenceRate;
    }
    mix_ingredient(mix_ingredient&& x)noexcept: ingre(new ingredient*[n])
    {
        for (int i = 0;i < n;i++)
            ingre[i] = x.ingre[i];
        weigh = x.weigh;
        fatWeigh = x.fatWeigh;
        glutenWeigh = x.glutenWeigh;
        condenceRate = x.condenceRate;
        x.ingre = NULL;
    }
    virtual mix_ingredient& operator=(const mix_ingredient& x)
    {
        mix_ingredient tmp(x);
        *this = std::move(tmp);
        return *this;
    }
    mix_ingredient& operator=(mix_ingredient&& x)noexcept
    {
        ingre = x.ingre;
        x.ingre = NULL;
        weigh = x.weigh;
        fatWeigh = x.fatWeigh;
        glutenWeigh = x.glutenWeigh;
        condenceRate = x.condenceRate;
        return *this;
    }
    ~mix_ingredient()
    {
        delete[] ingre;
    }
}mix;

void mix_ingredient::ini()
{
    weigh = 0;
    for (int i = 0;i < n;i++)
        weigh += ingre[i]->getWeigh();
    fatWeigh = 0;
    for (int i = 0;i < n;i++)
        if (ingre[i]->getWeigh() > 50)
            fatWeigh += ingre[i]->getFatWeigh();
    glutenWeigh = 0;
    for (int i = 0;i < n;i++)
        if (ingre[i]->getCondenceRate() < 60)
            glutenWeigh += ingre[i]->getGlutenWeigh();
    unsigned tmp = 0;
    for (int i = 0;i < n;i++)
        tmp = ingre[i]->getWeigh()*ingre[i]->getCondenceRate();
    condenceRate = tmp / weigh;

}

int mix_ingredient::put(ingredient * x)
{
    for (int i = 0;i < n;i++)
        if (ingre[i] == NULL)
        {
            ingre[i] = x;
            return 1;
        }
    return 0;
}
    class cake
{
private:
    char* name;
    ingredient** ingre;
    int n;
    unsigned weigh;
    unsigned fatWeigh;
    unsigned glutenWeigh;
    unsigned condenceRate;
public:
    unsigned getWeigh() { return weigh; }
    unsigned getFatWeigh() { return fatWeigh; }
    unsigned getGlutenWeigh() { return glutenWeigh; }
    unsigned getCondenceRate() { return condenceRate; }
public:
    cake(const char* name, int n)
    {
        this->name = new char[nameLength];
        strcpy(this->name, name);
        this->ingre = new ingredient*[n];
        this->n = n;
    }
    int put(ingredient* x)
    {
        for (int i = 0;i < n;i++)
            if (ingre[i] == NULL)
            {
                ingre[i] = x;
                return 1;
            }
        return 0;
    }
    void ini();
    void print();
public:
    cake() { name = new char[nameLength]; }
    cake(const cake& x) :name(new char[nameLength])
    {
        strcpy(name, x.name);
        ingre = new ingredient*(*(x.ingre));        
    }
    cake(cake&& x)noexcept: name(new char[nameLength])
    {
        strcpy(name, x.name);
        x.name = NULL;
        ingre = x.ingre;
        x.ingre = NULL;
    }
    cake& operator=(const cake& x)
    {
        cake tmp(x);
        *this = std::move(tmp);
        return *this;
    }
    cake& operator=(cake&& x)noexcept
    {
        name = x.name;
        x.name = NULL;
        ingre = x.ingre;
        x.ingre = NULL;
    }
    ~cake()
    {
        delete[] name;
        delete ingre;
    }
};

void cake::ini()
{
    weigh = 0;
    for (int i = 0;i < n;i++)
        weigh += ingre[i]->getWeigh();
    fatWeigh = 0;
    for (int i = 0;i < n;i++)
        if (ingre[i]->getWeigh() > 50)
            fatWeigh += ingre[i]->getFatWeigh();
    glutenWeigh = 0;
    for (int i = 0;i < n;i++)
        if (ingre[i]->getCondenceRate() < 60)
            glutenWeigh += ingre[i]->getGlutenWeigh();
    unsigned tmp = 0;
    for (int i = 0;i < n;i++)
        tmp = ingre[i]->getWeigh()*ingre[i]->getCondenceRate();
    condenceRate = tmp / weigh;
}

void cake::print()
{
    printf("%s", name);
}

int main()
{
    //Nguyên liệu nguyên chất
    //1
    raw powder("Bot my",100,0,76,100);
    //2
    raw egg("Trung", 100, 4, 1, 60);
    //3
    raw milk("Sua", 100, 1, 5, 100);
    //4
    raw gelatin("Gelatin", 100, 0, 14, 25);
    //5
    raw cream("Kem tuoi", 100, 8, 14, 70);
    //6
    raw creamCheese("Pho mai kem", 100, 11, 4, 70);
    //7
    raw sugar("Duong", 100, 0, 100, 100);
    //8
    raw cornPowder("Bot ngo", 100, 0, 79, 100);
    //9
    raw water("Nuoc", 100, 0, 0, 0);
    //10
    raw caramen("Caramen", 100, 1, 23, 90);
    //11
    raw flour("Bot nep", 100, 0, 21, 100);
    //12
    raw salt("Muoi", 100, 0, 0, 100);
    //13
    raw bakingPowder("Bot no", 100, 0, 28, 100);
    //Nguyên liệu hỗn hợp
    mix cakeMixture(4);
    cakeMixture.put(&powder);
    cakeMixture.put(&egg);
    cakeMixture.put(&milk);
    cakeMixture.put(&water);
    cakeMixture.ini();
    mix ladyFinger(5);
    ladyFinger.put(&powder);
    ladyFinger.put(&egg);
    ladyFinger.put(&sugar);
    ladyFinger.put(&cornPowder);
    ladyFinger.put(&salt);
    ladyFinger.ini();
    mix mochiMixture(3);
    mochiMixture.put(&sugar);
    mochiMixture.put(&water);
    mochiMixture.put(&caramen);
    mochiMixture.ini();
    mix mousseMixture(2);
    mousseMixture.put(&gelatin);
    mousseMixture.put(&cream);
    mousseMixture.ini();
    //Bánh
    cake pancake("Pancake",1);
    pancake.put(&cakeMixture);
    pancake.ini();
    cake mousse("Mousse", 1);
    mousse.put(&mousseMixture);
    mousse.ini();
    cake cheesecake("Banh pho mai", 2);
    cheesecake.put(&cream);
    cheesecake.put(&creamCheese);
    cheesecake.ini();
    cake tiramisu("Tiramisu", 1);
    tiramisu.put(&cream);
    tiramisu.ini();
    cake cupcake("Cupcake", 1);
    cupcake.put(&cakeMixture);
    cupcake.ini();
    cake muffin("Muffin", 1);
    muffin.put(&cakeMixture);
    muffin.ini();
    cake mochi("Mochi", 1);
    mochi.put(&mochiMixture);
    mochi.ini();
    cake flan("Flan", 2);
    flan.put(&cakeMixture);
    flan.put(&caramen);
    flan.ini();
    cake gato("Gato", 1);
    gato.put(&cakeMixture);
    gato.ini();
    cake donut("Donut", 2);
    donut.put(&powder);
    donut.put(&bakingPowder);
    donut.ini();
    cake bakery[] = { pancake,mousse,cheesecake,tiramisu,cupcake,muffin,mochi,flan,gato,donut };
    for (int i = 0;i < 10;i++)
    {
        bakery[i].print();
        printf("\n");
    }
    printf("Cac loai banh mem: \n");
    for (int i = 0;i < 10;i++)
    {
        if (bakery[i].getCondenceRate() < 20)
            bakery[i].print();
        printf("\n");
    }
    printf("Banh ngot va it beo: \n");
    for (int i = 0;i < 10;i++)
    {
        if (bakery[i].getGlutenWeigh()*100/bakery[i].getWeigh() >40 &&
            bakery[i].getFatWeigh() * 100 / bakery[i].getWeigh() <50)
            bakery[i].print();
        printf("\n");
    }
    return 0;
}

网站似乎正确地运行了我的代码,但是当我尝试使用我的VS2015社区时,它会返回“访问冲突读取位置”并在第196行中断。 我不知道为什么以及如何解决这个问题。我已经阅读了一些类似的问题,这些问题已经在堆栈溢出上发布但是找到了解决这个问题的好方法。所以,请保存我的一天! 真诚的,谢谢。

P / s:对于冒犯和语法不正确的事感到抱歉。

1 个答案:

答案 0 :(得分:3)

mix_ingredient的构造函数中,您创建了一个指针数组ingre = new ingredient*[n],但是您没有使用值初始化数组。

稍后在mix_ingredient::put中,检查这些值是否不是NULL。如果ingre中的数组值未初始化,则可能存在任何内容。它不必是NULL,如果用作地址,它很可能不会指向您的程序允许使用的任何地址空间。

稍后在mix_ingredient::ini中,您使用inge中的值,就像它指向对象ingredient一样,如果地址未指向有效对象,则会导致访问冲突。