简体   繁体   中英

Having a problem with placement-new!

I am having a problem placing an instance of my reference-counting Pointer <Type> class into my Array class. Using the debugger, it seems that the constructor is never called (which messes up the reference-count and causes a segfault down the line)!

My push_back function is:

void push_back(const T& element)
{
    if (length >= max)
        reallocate(max > 0 ? max * 2 : 1);

    new (&data[length]) T(element);
    ++length;
}

The reference-count is the same before new is called as after. I'm very sure this is the problem, but I can't figure out why the constructor wouldn't be called. Additionally Pointer::Pointer(...) compiles whether it takes a Pointer <T> & or a const Pointer <T> & (huh?), and has the problem regardless as well!

Maybe there are some details on placement new I am not taking into account. If anyone has some thoughts, they'd be much appreciated!

edit: [as requested, a relevant excerpt from Pointer]

// ...
private:
    T* p;

public:
    //! Constructor
    Pointer()
        : p(0)
    {

    }

    //! Copy Constructor
    template<class X> Pointer(Pointer<X>& other)
        : p(other.getPointer())
    {
        if (p)
            p->incrementRef();
    }

    //! Constructor (sets and increments p)
    Pointer(T* p)
        : p(p)
    {
        if (p)
            p->incrementRef();
    }

    //! Destructor (decrements p)
    ~Pointer()
    {
        if (p)
            p->decrementRef();
    }
// ...

I've also implemented operator = for Pointer <T> & and T* , as well as operator -> and operator T*

According to docs constructor should be called... Few things you can check:

To test pointer:

Pointer<int> p1(new int);
Pointer<int> p2(p1); // Does this call constructor properly?

To test array:

Array<std::string> array;
std::string str("bla");
array.push_back(str); // Does this call string's constructor

That's what fails, right?

Array<Pointer<int> > array;
Pointer<int> p1(new int);
array.push_back(p1);

If all else fails, you can always do this to surely invoke copy constructor or operator=

T* t = new (&data[length]) T();
*t = element;

Your comment and your code are out of sync:

//! Copy Constructor
template<class X> Pointer(Pointer<X>& other)

A constructor generated from a class template is not a copy constructor (there's a footnote in 12.8 [class.copy] that clarifies this), so won't prevent the compiler from generating a copy constructor for you. This generated constructor will be a better match for a standard copy as non-template functions are preferred to template functions in overload resolution.

It appears that you need to write an explicit copy constructor in your pointer class to get the desired effect.

Please post your Pointer class here. I would think that the T in this class is Pointer ? If so is the code supposed to do: new (&data[length]) Pointer(element);

which I'm having a hard time understanding..

why not just do: data[length] = element; I'm assuming data[length] is Pointer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM