0

I'm trying to do an exercise with copy assignment constructor, template and smart pointer

#include <iostream>

template <typename T>
class Stack {
private:
    enum {MAX = 10};
    std::unique_ptr<T[]> pitems;
    int size;
    int top;
public:
    Stack(int n = 10){
        size = n;
        top = -1;
        T* items = new T[n];
        pitems = std::make_unique<T[]>(size);
    }

    Stack(const Stack & st): size(st.size), top(st.top){
        //Costruttore di copia
        std::unique_ptr<T[]> pitems = std::make_unique<T[]>(size);
        memcpy(pitems.get(), st.pitems.get(), size);
    }

    ~Stack(){
        pitems.reset();
    }

    bool isempty(){
        if(top == -1) return true;
        return false;
    };
    bool isfull(){
        if(top == size-1) return true;
        return false;
    };
    // push() returns false if stack already is full, true otherwise
    bool push(const T & item){
        if(isfull() == false){
            pitems[top] = item;
            top++;
            return true;
        }
        return false;
    } // add item to stack
    // pop() returns false if stack already is empty, true otherwise
    bool pop(T & item){
        if(isempty()) return false;
        item = pitems[top-1];
        top--;
        return true;
    }

    Stack& operator=(const Stack & st){
        if(this != &st){
            this->size = st.size;
            this->top = st.top;

            this->pitems.reset(new T[this->size]);
            memcpy(this->pitems.get(), st.pitems.get(), st.size);
        }
    }
};


int main() {
    Stack<int> s = Stack<int>(2);
    std::cout << s.isempty() << std::endl;
    s.push(3);
    int p;
    std::cout << s.isfull() << std::endl;
    s.pop(p);
    std::cout << p << std::endl;

    Stack<int> j;
    j = s;
    std::cout << j.pop(p) << std::endl;

    return 0;
}

But when I try to copy j in s I get EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) from the compiler and I don't understand why. Futhermore I cannot understand why, when I check it with the compiler, the copy assignment operator is called twice. Sorry for the probably stupid question but I started some weeks ago to study C++.

Lorenzoi
  • 31
  • 2
  • 8
  • 1
    Look at your copy constructor. – 1201ProgramAlarm Jun 12 '20 at 17:48
  • Enable all warnings, e.g. with `-Wall`, and fix all of them first. You'll solve a lot of issues that way. – cigien Jun 12 '20 at 17:52
  • 2
    `memcpy(pitems.get(), st.pitems.get(), size)` -- This will fail miserably if `T` is a non-POD type. Try your code with `std::string` as the `T`, and you should see what I mean. Don't reach for `C` functions if you're a new programmer to C++. – PaulMcKenzie Jun 12 '20 at 18:04
  • Take a look at the [Copy and Swap Idiom.](https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom). It sometimes results in a less efficient assignment operator, but it is astoundingly simple to implement and nearly impossible to get wrong. I start with Copy and Swap and only change if testing finds that A) it is too slow and B) I desperately need that extra speed. – user4581301 Jun 12 '20 at 18:13
  • 1
    Also, the fix for that `memcpy` issue is is to use `std::copy`, not `std::memcpy`. A good compiler will optimize `std::copy` to `std::memcpy` if it detects the types are trivially-copyable. – PaulMcKenzie Jun 12 '20 at 18:16
  • Thank you all. I resolved using std::copy and taking a look at the warnings! – Lorenzoi Jun 12 '20 at 20:02

0 Answers0