抛出异常:读取访问冲突。这是 objects 数组中的 nullptr

Exception thrown: read access violation. this was nullptr in array of objects

我是一名参加 OOP 课程的 CS 学生,我不知道如何解决这个问题。我知道当 += 运算符试图将第一个元素添加到数组中时,'this' 是 nullptr 并抛出异常,但我不知道如何修复它。

购物清单 header 如下所示:

#include "Groceries.h"

class ShoppingList{
    Groceries* list;
    int size = 0, capacity = 2;
public:
//methods
     ShoppingList& operator+=( const Groceries& c);

operator+= 看起来像:

ShoppingList& ShoppingList::operator+=( const Groceries& c) {
    if (size == capacity) {
        Groceries* l1 = new Groceries[capacity * 2];
        l1 = list;
        list = l1;
        capacity *= 2;
    }
    list[size++]=c;//here is the exception
    return *this;
}

杂货 header 看起来像:

#include <string>
#include <iostream>
class Groceries {
    std::string product;
    int quantity;
public:
    Groceries() : product("empty"), quantity(0) {};
    Groceries(std::string s, int x) : product(s), quantity(x) {};
    Groceries(const Groceries& c);
    ~Groceries() {};
    std::string product();
    int quantity();
    void Print();
};

并且 main 必须看起来像

int main()
{
    ShoppingList L;
    (L += Groceries("bread", 5)) += Groceries("cheese", 2);
    L.Print();
//...
}

运算符主体中的这些语句

l1 = list;
list = l1;

没有意义。在第一个赋值语句之后存在内存泄漏,因为分配的内存地址丢失了。其实这两个语句等价于这个语句

list = list;

包括覆盖指针的副作用l1

运算符可以这样定义

ShoppingList& ShoppingList::operator+=( const Groceries& c) {
    if (size == capacity) {
        Groceries* l1 = new Groceries[capacity * 2];
        std::copy( list, list + size, l1 );
        delete [] list;
        list = l1;
        capacity *= 2;
    }
    list[size++]=c;//here is the exception
    return *this;
}

请注意,您使用相同的标识符 productquantity 来声明不同的实体

class Groceries {
    std::string product;
    int quantity;
public:
    //...
    std::string product();
    int quantity();
    //...

这是一个基于您的代码的演示程序。

#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>

class Groceries {
    std::string product;
    int quantity;
public:
    Groceries() : product("empty"), quantity(0) {};
    Groceries(std::string s, int x) : product(s), quantity(x) {};
    Groceries(const Groceries& c);
    ~Groceries() {};
//    std::string product();
//    int quantity();
    void Print();

    friend std::ostream & operator <<( std::ostream &os, const Groceries &g )
    {
        return os << g.product << ": " << g.quantity; 
    }
};

class ShoppingList{
    Groceries* list;
    int size = 0, capacity = 2;
public:
//methods
     ShoppingList& operator+=( const Groceries& c);
     ShoppingList() : list( new Groceries[2]() ) {}
     ~ShoppingList() { delete [] list; }

     friend std::ostream & operator <<( std::ostream &os, const ShoppingList &sl )
     {
        std::copy( sl.list, sl.list + sl.size, 
                   std::ostream_iterator<Groceries>( os, " " ) );
        return os;
     }
};

ShoppingList& ShoppingList::operator+=( const Groceries& c) {
    if (size == capacity) {
        Groceries* l1 = new Groceries[capacity * 2];
        std::copy( list, list + size, l1 );
        delete [] list;
        list = l1;
        capacity *= 2;
    }
    list[size++]=c;//here is the exception
    return *this;
}


int main() 
{
    ShoppingList L;
    (L += Groceries("bread", 5)) += Groceries("cheese", 2);

    std::cout << L << '\n';

    return 0;
}

程序输出为

bread: 5 cheese: 2