Два объекта, кажется, имеют один и тот же адрес

0

Я использую Visual Studio Ultimate 2013 Preview, Windows 7.

Я использую CRTP, чтобы иметь возможность удобно перемещать объекты любого типа в отдельный вектор.

Однако результаты довольно странные. Вы увидите, что у меня есть два класса: A и B которые выводятся из Container. С T* PushOne() новый экземпляр вставляется в статический вектор, и его адрес возвращается для использования.

По какой-то причине первый экземпляр-объект класса A и первый класс B похоже, имеют один и тот же адрес.

Здесь код:

template <typename T>
class Container{
public:
    static std::vector<T> elements;

    static T* PushOne(){
        //Push a new T object into the vector
        elements.push_back( T{} );
        //Print out its address
        std::cout << "Make " << typeid(T).name() << " at " << &elements[elements.size() - 1] << "\n";
        //Return its address.
        return &elements[elements.size() - 1];
    }
};

template <typename T> 
std::vector<T> Container<T>::elements;

class A : public Container<A>{
};

class B : public Container<B>{
};

int main(int argc, char** args){
    std::cout << "First addresses:\n";

    //a and c are assigned the address
    auto a = Container<A>::PushOne();
    auto b = Container<A>::PushOne(); //Problem gone if this is commented
    auto c = Container<B>::PushOne();

    std::cout << "\nLater addresses:\n";
    std::cout   << &Container<A>::elements[0] << "\n" 
                << &Container<A>::elements[1] << "\n" 
                << &Container<B>::elements[0] << "\n";

    std::cin.get();
}

Выход из одного запуска на моем компьютере:

First addresses:
Make class A at 00700350
Make class A at 006FA929
Make class B at 00700350

Later addresses:
006FA928
006FA929
00700350

Как вы можете видеть, первая и последняя запись (которые хранятся в переменных a и b соответственно) сначала печатают один и тот же адрес.

Когда я печатаю адреса во второй раз, я получаю другой результат для первого A *.

Я всегда получаю тот же результат, если не комментировать строку auto b =... Если я это сделаю, a и b назначаются разные адреса.

Теги:
visual-studio
templates

2 ответа

4
Лучший ответ

Второй push_back/PushOne приводит к перераспределению на вашем std::vector<A> чтобы увеличить его, так что теперь первый элемент A больше не находится в 00700350.

Распечатка вашего более Later addresses подтверждает это.

3

Когда вы нажимаете элементы на вектор, в конечном итоге ему нужно будет выделить новую память и освободить старую память (которую могут использовать другие распределения). Итак, по-видимому, когда вы отодвинули второй раз для Container<A>, произошло перераспределение. Затем, когда вы нажимаете Container<B>, его вектор использовал память, которую выпустил другой вектор (Container<A>). Это прекрасно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню