0xC0000005:访问冲突写入位置 0xCCCCCCCC 导致试图使安全空字符
0xC0000005: Access violation writing location 0xCCCCCCCC caused by trying to make safe empty chars
我一直在为某个似乎困扰我的程序的错误而烦恼。我试图在网上搜索与我类似的案例,但我似乎找不到将其他解决方案应用于此问题的方法。我的问题如下:当我最初打开程序时,它立即停止响应并崩溃。调试让我发现有问题的错误是“0xC0000005:访问冲突写入位置0xCCCCCCCC”。这似乎与我将两个属性(sku_ 和 name_)分配为“\0”有关。如果我将这些值更改为任何其他值,例如“”甚至“\0”,程序将在 visual studio 中运行,但将无法在其他地方编译。有人可以帮助我了解我哪里出错了吗?
Product.h
#ifndef SICT_Product_H__
#define SICT_Product_H__
#include "general.h"
#include "Streamable.h"
#include <cstring>
namespace sict {
class Product : public Streamable {
char sku_ [MAX_SKU_LEN + 1];
char* name_;
double price_;
bool taxed_;
int quantity_;
int qtyNeeded_;
public:
//Constructors
Product();
Product(const char* sku, const char* name1, bool taxed = true, double price = 0, int qtyNeeded =0);
Product(Product& g);
~Product();
//Putter Functions
void sku(const char* sku) { strcpy(sku_,sku); };
void price(double price) {price_ = price;};
void name(const char* name);
void taxed(bool taxed) { taxed_ = taxed; };
void quantity(int quantity) { quantity_ = quantity; };
void qtyNeeded(int qtyNeeded) { qtyNeeded_ = qtyNeeded; };
//Getter functions
const char* sku() const { return sku_; };
double price() const { return price_; };
const char* name() const { return name_; };
bool taxed() const { return taxed_; };
int quantity() const { return quantity_; };
int qtyNeeded() const { return qtyNeeded_; };
double cost() const;
bool isEmpty() const;
Product& operator=(const Product& );
bool operator==(const char* );
int operator+=(int );
int operator-=(int );
};
double operator+=(double& , const Product& );
std::ostream& operator<<(std::ostream& os, const Product& );
std::istream& operator>>(std::istream& is, Product& );
}
#endif
Product.cpp
#include <iostream>
#include <cstring>
#include "Product.h"
namespace sict {
Product::Product() {
sku_[0] = '[=11=]';
name_[0] = '[=11=]';
price_ = 0;
quantity_ = 0;
qtyNeeded_ = 0;
}
Product::Product(const char* sku, const char* name1, bool taxed1, double price1, int qtyNeeded1) {
strncpy(sku_, sku, MAX_SKU_LEN);
name(name1);
quantity_ = 0;
taxed(taxed1);
price(price1);
qtyNeeded(qtyNeeded1);
}
double Product::cost() const {
if (taxed_ == true) {
return (price_ * TAX) + price_;
}
else
return price_;
}
bool Product::isEmpty() const{
if (sku_ == nullptr && name_ == nullptr && quantity_ == 0 && price_ == 0 && qtyNeeded_ == 0) {
return true;
}
else
return false;
}
Product::Product(Product& ex) {
sku(ex.sku_);
price(ex.price_);
name(ex.name_);
taxed(ex.taxed_);
quantity(ex.quantity_);
qtyNeeded(ex.qtyNeeded_);
}
Product& Product::operator=(const Product& g) {
sku(g.sku_);
price(g.price_);
name(g.name_);
taxed(g.taxed_);
quantity(g.quantity_);
qtyNeeded(g.qtyNeeded_);
return *this;
}
Product::~Product() {
delete [] name_;
}
void Product::name(const char* name) {
name_ = new char [strlen(name) + 1];
strcpy(name_, name);
}
bool Product::operator==(const char* right) {
if (sku_ == right) {
return true;
}
else
return false;
}
int Product::operator+=(int g) {
quantity_ = quantity_ + g;
return quantity_;
}
int Product::operator-=(int g) {
quantity_ = quantity_ - g;
return quantity_;
}
double operator+=(double& p, const Product& right) {
p = p + (right.cost() * right.quantity());
return p;
}
std::ostream& operator<<(std::ostream& os, const Product& g) {
return g.write(os, true);
}
std::istream& operator>>(std::istream& is, Product& g) {
return g.read(is);
}
}
header 中引用的 General.h 文件只是一个常数值列表,例如 "TAX" 和 "MAX_SKU_LEN" 值。
Streamable header 包含纯虚函数。我会在这里列出它以备不时之需。
Streamable.h
#ifndef SICT__Streamable_H_
#define SICT__Streamable_H_
#include <iostream>
#include <fstream>
#include "Product.h"
namespace sict {
class Streamable {
public:
virtual std::fstream& store(std::fstream& file, bool addNewLine = true)const = 0;
virtual std::fstream& load(std::fstream& file) = 0;
virtual std::ostream& write(std::ostream& os, bool linear)const = 0;
virtual std::istream& read(std::istream& is) = 0;
};
}
#endif
非常感谢您。
Product::Product() {
sku_[0] = '[=10=]';
name_[0] = '[=10=]'; // <---- writing via unitialized pointer
price_ = 0;
quantity_ = 0;
qtyNeeded_ = 0;
}
您的问题可能有一个原因。您已经在 class 中定义了一个 char 指针(动态数组或 C 字符串)name_
,但是在尝试通过以下方式记录值之前,您从未在构造函数中为其分配任何内存指针。自然地,您会遇到写访问冲突。
在将值分配给索引 [0] 处的 char 之前,您需要先为字符串中的至少一个元素分配 space,例如通过 name_ = new char [1]
。或者,您可以选择将指针本身初始化为 NULL(或 nullptr)并使用它来指示尚未设置 name_
。
我一直在为某个似乎困扰我的程序的错误而烦恼。我试图在网上搜索与我类似的案例,但我似乎找不到将其他解决方案应用于此问题的方法。我的问题如下:当我最初打开程序时,它立即停止响应并崩溃。调试让我发现有问题的错误是“0xC0000005:访问冲突写入位置0xCCCCCCCC”。这似乎与我将两个属性(sku_ 和 name_)分配为“\0”有关。如果我将这些值更改为任何其他值,例如“”甚至“\0”,程序将在 visual studio 中运行,但将无法在其他地方编译。有人可以帮助我了解我哪里出错了吗?
Product.h
#ifndef SICT_Product_H__
#define SICT_Product_H__
#include "general.h"
#include "Streamable.h"
#include <cstring>
namespace sict {
class Product : public Streamable {
char sku_ [MAX_SKU_LEN + 1];
char* name_;
double price_;
bool taxed_;
int quantity_;
int qtyNeeded_;
public:
//Constructors
Product();
Product(const char* sku, const char* name1, bool taxed = true, double price = 0, int qtyNeeded =0);
Product(Product& g);
~Product();
//Putter Functions
void sku(const char* sku) { strcpy(sku_,sku); };
void price(double price) {price_ = price;};
void name(const char* name);
void taxed(bool taxed) { taxed_ = taxed; };
void quantity(int quantity) { quantity_ = quantity; };
void qtyNeeded(int qtyNeeded) { qtyNeeded_ = qtyNeeded; };
//Getter functions
const char* sku() const { return sku_; };
double price() const { return price_; };
const char* name() const { return name_; };
bool taxed() const { return taxed_; };
int quantity() const { return quantity_; };
int qtyNeeded() const { return qtyNeeded_; };
double cost() const;
bool isEmpty() const;
Product& operator=(const Product& );
bool operator==(const char* );
int operator+=(int );
int operator-=(int );
};
double operator+=(double& , const Product& );
std::ostream& operator<<(std::ostream& os, const Product& );
std::istream& operator>>(std::istream& is, Product& );
}
#endif
Product.cpp
#include <iostream>
#include <cstring>
#include "Product.h"
namespace sict {
Product::Product() {
sku_[0] = '[=11=]';
name_[0] = '[=11=]';
price_ = 0;
quantity_ = 0;
qtyNeeded_ = 0;
}
Product::Product(const char* sku, const char* name1, bool taxed1, double price1, int qtyNeeded1) {
strncpy(sku_, sku, MAX_SKU_LEN);
name(name1);
quantity_ = 0;
taxed(taxed1);
price(price1);
qtyNeeded(qtyNeeded1);
}
double Product::cost() const {
if (taxed_ == true) {
return (price_ * TAX) + price_;
}
else
return price_;
}
bool Product::isEmpty() const{
if (sku_ == nullptr && name_ == nullptr && quantity_ == 0 && price_ == 0 && qtyNeeded_ == 0) {
return true;
}
else
return false;
}
Product::Product(Product& ex) {
sku(ex.sku_);
price(ex.price_);
name(ex.name_);
taxed(ex.taxed_);
quantity(ex.quantity_);
qtyNeeded(ex.qtyNeeded_);
}
Product& Product::operator=(const Product& g) {
sku(g.sku_);
price(g.price_);
name(g.name_);
taxed(g.taxed_);
quantity(g.quantity_);
qtyNeeded(g.qtyNeeded_);
return *this;
}
Product::~Product() {
delete [] name_;
}
void Product::name(const char* name) {
name_ = new char [strlen(name) + 1];
strcpy(name_, name);
}
bool Product::operator==(const char* right) {
if (sku_ == right) {
return true;
}
else
return false;
}
int Product::operator+=(int g) {
quantity_ = quantity_ + g;
return quantity_;
}
int Product::operator-=(int g) {
quantity_ = quantity_ - g;
return quantity_;
}
double operator+=(double& p, const Product& right) {
p = p + (right.cost() * right.quantity());
return p;
}
std::ostream& operator<<(std::ostream& os, const Product& g) {
return g.write(os, true);
}
std::istream& operator>>(std::istream& is, Product& g) {
return g.read(is);
}
}
header 中引用的 General.h 文件只是一个常数值列表,例如 "TAX" 和 "MAX_SKU_LEN" 值。 Streamable header 包含纯虚函数。我会在这里列出它以备不时之需。
Streamable.h
#ifndef SICT__Streamable_H_
#define SICT__Streamable_H_
#include <iostream>
#include <fstream>
#include "Product.h"
namespace sict {
class Streamable {
public:
virtual std::fstream& store(std::fstream& file, bool addNewLine = true)const = 0;
virtual std::fstream& load(std::fstream& file) = 0;
virtual std::ostream& write(std::ostream& os, bool linear)const = 0;
virtual std::istream& read(std::istream& is) = 0;
};
}
#endif
非常感谢您。
Product::Product() {
sku_[0] = '[=10=]';
name_[0] = '[=10=]'; // <---- writing via unitialized pointer
price_ = 0;
quantity_ = 0;
qtyNeeded_ = 0;
}
您的问题可能有一个原因。您已经在 class 中定义了一个 char 指针(动态数组或 C 字符串)name_
,但是在尝试通过以下方式记录值之前,您从未在构造函数中为其分配任何内存指针。自然地,您会遇到写访问冲突。
在将值分配给索引 [0] 处的 char 之前,您需要先为字符串中的至少一个元素分配 space,例如通过 name_ = new char [1]
。或者,您可以选择将指针本身初始化为 NULL(或 nullptr)并使用它来指示尚未设置 name_
。