0
votes

I need to create a class like this. But when I run this code, I get:

"Error in `./a.out': free(): invalid next size (fast)"

What's wrong with MyClass? How to use shared_ptr as a class member correctly?

#include <memory>

class MyClass
{
public:
    MyClass(unsigned size) {
        _size = size;
        _arr = std::make_shared<int>(size);
        for (int i = 0; i < size; i++)
            _arr.get()[i] = 0;
    }

    MyClass(const MyClass& other) {
        _arr = other._arr;
        _size = other._size;
    }

    MyClass& operator=(const MyClass& other) {
        _arr = other._arr;
        _size = other._size;
    }

    void setArr(std::shared_ptr<int> arr, unsigned size) {
        _size = size;
        _arr = arr;
    }

    ~MyClass() {
        _arr.reset();
    }

private:
    std::shared_ptr<int> _arr;
    unsigned _size;
};

int main() {
    MyClass m(4);
    return 0;
}

Thank you, I misunderstood what make_shared makes. If I want to use int* (not std::vector or std::array), should I write this? (and don't fix the other methods)

    MyClass(unsigned size) {
        _size = size;
        _arr = std::shared_ptr<int>(new int[size]);
        for (int i = 0; i < size; i++)
            _arr.get()[i] = 0;
    }
1
Hint: pointers are not arrays. Think carefully about what this means: std::make_shared<int>(size);.juanchopanza
Also note that your issue has nothing to do with the smart pointer being a data member.juanchopanza
You say you "need to create a class like this" and that you don't "want to use" the easy standard solution (std::vector). Why? What is the reason that you absolutely must use std::shared_ptr?Christian Hackl
@AnatoliySultanov: Have you considered std::shared_ptr<std::vector<int>>?Christian Hackl
@AnatoliySultanov: Yes, do you do need a "dynamic array" (i.e. a std::vector in real code, unless you have a very special use case that demands manual use of placement new) if the size is only known at run-time.You can use std::array only if you know the size before the program runs. Just don't use new[], ever.Christian Hackl

1 Answers

3
votes

Please, look how std::make_shared works.

Basically, std::make_shared

Constructs an object of type T and wraps it in a std::shared_ptr

In your case T is int, so std::make_shared created an object of type int and wraps it in a std::shared_ptr. As a result memory is allocated for a single int, not for an array of ints and your program causes Undefined Behaviour.

I suppose you can use std::default_delete to avoid problems:

_arr = std::shared_ptr<int>(new int[size], std::default_delete<int[]>());

Also note, that:

  1. Your operator= returns nothing.
  2. You shouldn't start variables names with an underscore.
  3. It's not necessary to call reset() for _arr in the class destructor.