C++ Int 似乎没有初始化并抛出异常:读取访问冲突

Posted

技术标签:

【中文标题】C++ Int 似乎没有初始化并抛出异常:读取访问冲突【英文标题】:C++ Int doesn't seem to be initializing and Exception thrown: read access violation 【发布时间】:2017-03-04 03:23:10 【问题描述】:

我对 C++ 很陌生,所以请原谅草率的代码。 这是有问题的代码:

包类

class Bag 
protected:
    Item* _myItems;
    int _numItems;
    int _size;
public:
    Bag();
    Bag(int size);
    ~Bag();
    Bag(Bag& original);
    void add(Item a);
    void remove(int itemnum);
    int size();
    int numItems();
    void operator=(Bag& bag);
    Item& operator[] (int i);
;

//Empty constructor
Bag::Bag() 
    _numItems = 0;


//overloaded constructor
Bag::Bag(int size) 
    _numItems = 0;
    _myItems = new Item[size];


//copy constructor
Bag::Bag(Bag& original) 
    //Copies the numItems
    _numItems = original._numItems;
    //Makes a new copy of the original array
    _myItems = new Item[_numItems];
    //Copies each element of the original into the new
    for (int i = 0; i < _numItems; ++i) 
        _myItems[i] = original[i];
    


//Destructor
Bag::~Bag()
    delete[] _myItems;


//Returns the size of the bag
int Bag::size()

    return _size;


//Returns the number of items in the bag
int Bag::numItems() 
    return _numItems;


//Add a new item to the bag
void Bag::add(Item a) 
    int s = _numItems;
    //Create a Item pointer and assign it to the array of the bag
    Item* temp = _myItems;
    //Assign _myItems to a new, larger array
    _myItems = new Item[_numItems++];
    //Copy the old array into the new one and nullify all the old array's items
    for (int i = 0; i < _numItems - 1; i++)  
        _myItems[i] = temp[i];  
    
    //Destroy the old array
    delete[] temp;
    //Add the item to the last position
    _myItems[_numItems] = a;

我正在逐行读取文本文件。阅读似乎进行得很好。当我阅读时,我执行这部分代码:

//The main program
int main() 

    Pens * onePen = new Pens(1, 2);
    Pens * twoPen = new Pens(2, 3);

    Bag* bag = new Bag(5);

    (*bag).add(onePen);
    (*bag).add(twoPen);

    bag[0];
    bag[1];

    int d = 0;

    return 0;

当我进入 add 方法时,我不断收到读取访问冲突(这是 0xc)。我还注意到,当我设置断点检查代码时,_numItems 不是 0 而是 211。我是否以某种方式破坏了我的内存?

Here is a sample text file that we are using

Bag 和 Pen 类的简化版本(由 PaulMcKenzie 提供):

class Item 
protected:
    int code_;

    //Sets the method definition for the get/set methods and constructors
public:
    Item(int code = -1);
    virtual ~Item() 
    int getcode() const;
    void setcode(int code);
    std::ostream& operator<< (std::ostream& s);
    bool operator== (const Item& a) const;
;

Item::Item(int code) : code_(code) 
int Item::getcode() const  return code_; 
void Item::setcode(int code)  code_ = code; 

std::ostream & Item::operator<<(std::ostream& s)

    s << " Code - " << code_ << "\n";
    return s;


bool Item::operator==(const Item & a) const

    return (code_ == a.getcode());


class Pens : public Item

private: int packetsize_;
public:
    Pens();
    Pens(int code, int packetsize);
    int getpacketsize() const;
    void setpacketsize(int packetsize);
    bool operator== (const Pens& a) const;
;

Pens::Pens() :Item()  
Pens::Pens(int code, int packetsize) : Item(code), packetsize_(packetsize) 
int Pens::getpacketsize() const  return packetsize_; 
void Pens::setpacketsize(int packetsize)  packetsize_ = packetsize; 

std::ostream& operator<<(std::ostream& s, const Pens& pen)

    s << " Packet size: " << pen.getpacketsize() << "\n";
    return s;


bool Pens::operator==(const Pens & a) const

    return code_ == a.getcode() && packetsize_ == a.getpacketsize();

【问题讨论】:

要准确回答您提出的问题:是的,您正在破坏内存。我看到至少有两个不同的地方会破坏记忆。免费线索#1,如果对象是默认构造的,析构函数delete[] 会是什么?免费线索#2:如果当add() 被称为numItems_ 时,比如说,2,而myItems_ 大概是一个包含两个值的数组,那么新的替换myItems_ 数组会有多大,@987654330 @new-s 在那里?免费线索 #3:不,新数组不会包含 3 个值。 以下程序产生问题:Bag b;。原因是你没有在你的默认构造函数中初始化成员指针,而析构函数在一个未初始化的指针上调用delete[] 另一个问题是您使用不同的Item 类型调用add(),并且您通过值传递Item。这会创建一个称为对象切片的条件。代码有很多问题——为什么作为 C++ 的初学者,你要编写只有中级到高级 C++ 程序员才应该尝试的代码? @PaulMcKenzie 这是一个数据结构类。他们基本上是从上学期预习课中使用的Java跳到本课程中的C++。讲师为我们提供 C++ 项目。我们在课堂上介绍了比 C++ 工作原理更多的数据结构概念...... @DavidNettey - 使用 C++ 实现数据结构的问题是有两个障碍需要克服——第一个是 C++ 语言本身,第二个是数据结构的实现。使用 Java,您没有“语言障碍”,因为您没有指针、对象被垃圾回收等。问题是您确实需要成为高级 C++ 程序员的中级首先实现数据结构。初学者不可能(或很少有机会)在 C++ 中正确实现这一点。 【参考方案1】:

我没有深入研究,但这段片段引起了我的注意:

//Add a new item to the bag
void Bag::add(Item a) 
int s = _numItems;
//Create a Item pointer and assign it to the array of the bag
Item* temp = _myItems;
//Assign _myItems to a new, larger array
_myItems = new Item[_numItems++];
//Copy the old array into the new one and nullify all the old array's items
for (int i = 0; i < _numItems - 1; i++)  
    _myItems[i] = temp[i];  

//Destroy the old array
delete[] temp;
//Add the item to the last position
_myItems[_numItems] = a;

请看这一行:

_myItems = new Item[_numItems++];

您创建大小为 _numItems 的新数组,然后_numItems 增加 1。

以我的拙见,这会让您得到大小为 _numItems-1 的数组。 然后你尝试使用元素 _myItems[_numItems] 所以这可能是内存损坏的原因。

【讨论】:

我明白了!会这样称呼它:_myItems = new Item[++_numItems];改变那个? 刚试了一下,把 add 方法的最后一个like 改成 _myItems[_numItems - 1] = a 就成功了!但是我似乎无法添加其他项目..

以上是关于C++ Int 似乎没有初始化并抛出异常:读取访问冲突的主要内容,如果未能解决你的问题,请参考以下文章

从 C# 调用 C++ dll 并抛出 SEHException

如何限制对任何路由的直接访问并抛出 404 异常,即使存在路由?

0xC0000005 读取二进制文件时抛出异常(C++)

C++ Battle4Zion 项目抛出未处理的异常:读取访问冲突。 **this** 是 nullptr。发生了

异常处理——捕获并抛出

抛出异常:读取访问冲突。 **bp** 为 0xFFFFFFFFFFFFFFFF