MS4:Free(Free()无效指针0xB74E74E0 ***



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

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

错误。我不确定此错误是什么意思或发生在哪里。对此的任何帮助将不胜感激。谢谢。

nonrish.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] == '' && m_name == nullptr && m_unit[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;
    }
}

不可腐烂的

#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 = '');
    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

我尝试在线寻找解决方案,但尚未找到任何解决方案。我希望经验丰富的人能有所帮助。

在复制构造函数

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指针来避免所有这些。

最新更新