ms4:free()无效指针0xb74e74e0 ***

时间:2017-12-18 02:28:19

标签: c++

当我尝试编译代码时,我得到了

  

*检测到glibc * ms4:free()无效指针0xb74e74e0 ***

错误。我不确定这个错误意味着什么或它发生在哪里。任何有关这方面的帮助将非常感激。谢谢。

NonPerishable.cpp

#include <iostream>
#include <cstring>
#include <fstream>
#include <iomanip>
#include "NonPerishable.h"
#include "ErrorMessage.h"

namespace sict {

using namespace std;

void NonPerishable::name(const char* cName) {

    if (m_name != nullptr) {

        delete[] m_name;

    }

    if (cName != nullptr) {

        m_name = nullptr;
        m_name = new char[strlen(cName) + 1];
        strcpy(m_name, cName);

    }
}

const char* NonPerishable::name() const {

    return m_name;

}

double NonPerishable::cost() const {

    double final = m_price;

    if (m_taxable) {

        final += (m_price * taxRate);

    }

    return final;

}

void NonPerishable::message(const char* msg) {

    this->m_error.message(msg);

}

bool sict::NonPerishable::isClear() const {

    return m_error.isClear();

}

NonPerishable::NonPerishable(const char type) {

    m_prodType = type;
    strcpy(m_sku, "");
    m_name = nullptr;
    strcpy(m_unit, "");
    m_quantity = 0;
    m_amountNeeded = 0;
    m_price = 0.0;
    m_taxable = true;
    m_error.clear();

}

NonPerishable::NonPerishable(const char* sku, const char* name, const char* unit, int quantity, bool taxable, double price, int needed) {

    m_prodType = 'N';
    strcpy(m_sku, sku);
    m_name = nullptr;
    strcpy(m_unit, unit);
    m_quantity = quantity;
    m_amountNeeded = needed;
    m_price = price;
    m_taxable = taxable;
    m_error.clear();
    this->name(name);

}

NonPerishable::NonPerishable(const NonPerishable& obj) {

    m_prodType = 'N';
    strcpy(m_sku, obj.m_sku);
    strcpy(m_unit, obj.m_unit);
    m_quantity = obj.m_quantity;
    m_amountNeeded = obj.m_amountNeeded;
    m_price = obj.m_price;
    m_taxable = obj.m_taxable;
    this->name(obj.m_name);

}

NonPerishable& NonPerishable::operator=(const NonPerishable& obj) {

    m_prodType = 'N';
    strcpy(m_sku, obj.m_sku);
    strcpy(m_unit, obj.m_unit);
    m_quantity = obj.m_quantity;
    m_amountNeeded = obj.m_amountNeeded;
    m_price = obj.m_price;
    m_taxable = obj.m_taxable;
    this->name(obj.m_name);

    /*if (!obj.m_error.isClear()) {

        m_error.message(obj.m_error.message());

    }*/

    return *this;

}

NonPerishable::~NonPerishable() {

    if (m_name != nullptr) {

        delete[] m_name;

    }
}

std::fstream& NonPerishable::store(std::fstream& file, bool newLine) const {

    if (!isEmpty()) {

        file << m_prodType << "," << m_sku << "," << m_name << "," << m_unit << "," << m_quantity << "," << m_amountNeeded << "," << m_price << "," << m_taxable << "," << m_error.message();

        if (newLine) {

            file << endl;

        }
    }

    return file;

}

std::fstream& NonPerishable::load(std::fstream& file) {

    char empty;

    file >> m_prodType >> empty >> m_sku >> empty >> m_name >> empty >> m_unit >> empty >> m_quantity >> empty >> m_amountNeeded >> empty >> m_price >> empty >> m_taxable;

    return file;

}

std::ostream& NonPerishable::write(std::ostream& os, bool linear) const {

    if (!isEmpty()) {

        if (linear) {

            os << setw(max_sku_length) << m_sku << "|" << setw(20) << m_name << "|" << setw(7) << m_price << "|" << setw(4) << m_quantity << "|" << setw(10) << m_unit << "|" << setw(4) << m_amountNeeded;

        }

        else {

            os << "Sku: " << m_sku << endl
                << "Name: " << m_name << endl
                << "Price: " << m_price << endl;

            if (m_taxable) {

                os << "Price after tax: " << total_cost() << endl;

            }

            else {

                os << "N/A" << endl;

            }

            os << "Quantity on Hand: " << m_quantity << endl
                << "Quantity Needed: " << m_amountNeeded << endl;

        }
    }

    return os;

}

std::istream& NonPerishable::read(std::istream& is) {

    char tempChar;
    bool valid = false;
    double tempNum;
    int tempInt;

    cout << "Sku: ";
    is >> m_sku;
    cout << "Name: ";
    is >> m_name;
    cout << "Unit: ";
    is >> m_unit;
    cout << "Taxed? (y/n): ";
    is >> tempChar;

    if (tempChar == 'y' || tempChar == 'Y') {

        m_taxable = true;
        valid = true;

    }

    if (tempChar == 'n' || tempChar == 'N') {

        m_taxable = false;
        valid = true;

    }

    if (!valid) {

        is.istream::setstate(std::ios::failbit);
        m_error.message("Only (Y)es or (N)o are acceptable");

    }

    cout << "Price: ";
    is >> tempNum;

    if (tempNum >= 0) {

        m_price = tempNum;

    }

    if (is.std::ios::fail()) {

        m_error.message("Invalid Price Entry");

    }

    cout << "Quantity on Hand: ";
    is >> tempInt;

    if (tempInt >= 0) {

        m_quantity = tempInt;

    }

    if (is.std::ios::fail()) {

        m_error.message("Invalid Quantity Entry");

    }

    cout << "Quantity Needed: ";
    is >> tempInt;

    if (tempInt >= 0) {

        m_amountNeeded = tempInt;

    }

    if (is.std::ios::fail()) {

        m_error.message("Invalid Quantity Needed Entry");

    }

    return is;

}

bool NonPerishable::operator==(const char* sku) const {

    if (strcmp(sku, this->m_sku) == 0) {

        return true;

    }
    else {

        return false;

    }
}

double NonPerishable::total_cost() const {

    double total = m_price * m_quantity;

    if (m_taxable) {

        total += ((m_price * m_quantity) * taxRate);

    }

    return total;

}

void NonPerishable::quantity(int amount) {

    m_quantity = amount;

}

bool NonPerishable::isEmpty() const {

    if (m_sku[0] == '\0' && m_name == nullptr && m_unit[0] == '\0' && m_quantity == 0 && m_amountNeeded == 0 && m_price == 0 && m_taxable == true) {

        return true;

    }
    else {

        return false;

    }
}

int NonPerishable::qtyNeeded() const {

    return m_amountNeeded;

}

int sict::NonPerishable::quantity() const {

    return m_quantity;

}

bool NonPerishable::operator>(const char* sku) const {

    if (m_sku > sku) {

        return true;

    }
    else {

        return false;

    }
}

int NonPerishable::operator+=(int units) {

    if (units > 0) {

        m_quantity += units;
        m_amountNeeded -= units;

    }

    return m_quantity;

}

bool NonPerishable::operator>(const Product& obj) const {

    if (m_name > obj.name()) {

        return true;

    }
    else {

        return false;

    }
}

std::ostream& operator<<(std::ostream& os, const Product& obj) {

    obj.write(os, true);

    return os;

}

std::istream& operator>>(std::istream& is, Product& obj) {

    obj.read(is);

    return is;

}

double operator+=(double& cost, const Product& obj) {

    return (cost + obj.total_cost());

}

Product* CreateProduct() {

    Product* temp = nullptr;
    temp = new NonPerishable;

    return temp;

    }
}

NonPerishable.h

#ifndef SICT_NONPERISHABLE_H
#define SICT_NONPERISHABLE_H

#include "Product.h"
#include "ErrorMessage.h"

namespace sict {

const int max_sku_length = 7;
const int max_unit_length = 10;
const int max_name_length = 75;
const double taxRate = 0.13;

class NonPerishable : public Product {

    char m_prodType;
    char m_sku[max_sku_length];
    char* m_name;
    char m_unit[max_unit_length];
    int m_quantity;
    int m_amountNeeded;
    double m_price;
    bool m_taxable;
    ErrorMessage m_error;

protected:

    void name(const char* name);
    const char* name() const;
    double cost() const;
    void message(const char* msg);
    bool isClear() const;

public:

    NonPerishable(const char type = '\0');
    NonPerishable(const char* sku, const char* name, const char* unit, int quantity = 0, bool taxable = true, double price = 0, int needed = 0);
    NonPerishable(const NonPerishable& obj);
    NonPerishable& operator=(const NonPerishable& obj);
    ~NonPerishable();

    std::fstream& store(std::fstream& file, bool newLine = true) const;
    std::fstream& load(std::fstream& file);
    std::ostream& write(std::ostream& os, bool linear) const;
    std::istream& read(std::istream& is);

    bool operator==(const char* sku) const;
    double total_cost() const;
    void quantity(int amount);
    bool isEmpty() const;
    int qtyNeeded() const;
    int quantity() const;
    bool operator>(const char* sku) const;
    int operator+=(int units);
    bool operator>(const Product& obj) const;

};

std::ostream& operator<<(std::ostream& os, const Product& obj);
std::istream& operator>>(std::istream& is, Product& obj);
double operator +=(double& cost, const Product& obj);
Product* CreateProduct();

}
#endif

我曾尝试在网上寻找解决方案,但没有找到任何解决方案。我希望有经验的人可以提供帮助。

1 个答案:

答案 0 :(得分:0)

在复制构造函数中

NonPerishable::NonPerishable(const NonPerishable& obj) {

    m_prodType = 'N';
    strcpy(m_sku, obj.m_sku);
    strcpy(m_unit, obj.m_unit);
    m_quantity = obj.m_quantity;
    m_amountNeeded = obj.m_amountNeeded;
    m_price = obj.m_price;
    m_taxable = obj.m_taxable;
    this->name(obj.m_name);

}

你永远不会初始化m_name。这可能会导致this->name(obj.m_name);调用删除未初始化的指针。

同样在name函数

void NonPerishable::name(const char* cName) {

    if (m_name != nullptr) {

        delete[] m_name;

    }

    if (cName != nullptr) {

        m_name = nullptr;
        m_name = new char[strlen(cName) + 1];
        strcpy(m_name, cName);

    }
}

如果cName恰好是nullptr,您将删除m_name但不会为其提供新值。这将导致稍后的双重删除,就像在析构函数中一样。

使用std::string代替char指针可以避免所有这些。