1

I'm a CS student taking an OOP course and I don't know how to fix this issue. I understand that when the += operator tries to add the first element into the array, 'this' is nullptr and an exception is thrown, but I don't know how to fix it.

Shopping list header looks like this:

#include "Groceries.h"

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

operator+= looks like:

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;
}

Groceries header looks like:

#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();
};

and main HAS TO look like

int main()
{
    ShoppingList L;
    (L += Groceries("bread", 5)) += Groceries("cheese", 2);
    L.Print();
//...
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335

1 Answers1

0

These statements in the body of the operator

l1 = list;
list = l1;

do not make sense. After the first assignment statement there is a memory leak because the address of the allocated memory is lost. In fact these two statements are equivalent to this statement

list = list;

including the side effect of the overwriting the pointer l1.

The operator can be defined the following way

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;
}

Pay attention to that you are using the same identifiers product and quantity to declare different entities

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

Here is a demonstrative program based on your code.

#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;
}

The program output is

bread: 5 cheese: 2 
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • The exception is still there. It's triggered in a string function, basic_string& assign(_In_reads_(_Count) const _Elem* const _Ptr, _CRT_GUARDOVERFLOW const size_type _Count) – stack_is_still_corrupted May 11 '20 at 11:41
  • @stack_is_still_corrupted You provided a code snippet that does not even compile. I showed in my answer how to change the operator +=. The error you are getting is result of other drawbacks of your code. For example you could forget to define the copy assignment operator or something else. – Vlad from Moscow May 11 '20 at 11:46
  • @stack_is_still_corrupted The question with the definition of the operator += is solved. Close this question selecting the best answer and ask a new one describing the new error of the code providing a minimal complete program that demonstrates the problem. – Vlad from Moscow May 11 '20 at 11:47