Может ли адрес объекта измениться? - PullRequest
0 голосов
/ 18 февраля 2019

Я хотел бы использовать std::map (или проб. std::unordered_map), где я вставляю пользовательские ключи объекта и двойные значения, например std::map<CustomClass,double>.Порядок объектов не имеет значения, важен только (быстрый) поиск.Моя идея заключается в том, чтобы вместо этого вставить адрес / указатель объекта, так как для него уже определен компаратор, т. Е. std::map<CustomClass*,double>

В Указатели в качестве ключей на карте C ++ STL на которые уже дан ответчто это можно сделать, но я все еще немного обеспокоен тем, что могут быть побочные эффекты, которые трудно уловить позже.

В частности: может ли адрес объекта измениться во время выполнения программы?И может ли это привести к неопределенному поведению моего поиска на карте?

Тестовая программа может выглядеть так:

auto a = adlib::SymPrimitive();
auto b = adlib::SymPrimitive();

auto c = adlib::mul(a,b);
auto d = adlib::add(c,a);

// adlib::Assignment holds std::map which assigns values to a,b
auto assignment = adlib::Assignment({&a,&b},{4,2});
// a=4, b=2 -> c=8 -> d=12
adlib::assertEqual(d.eval_fcn(assignment), 12);

, то есть код пользователя, поэтому пользователи потенциально могут поместить переменные в вектори т. д.

Обновление: ответы позволяют мне думать о пользователях, которые потенциально могут вставить SymPrimitives в вектор, простой сценарий будет такой:

std::vector<adlib::SymPrimitive> syms{a,b};
auto assignment = adlib::Assignment({&syms[0],&syms[1]},{4,2}); // not allowed

Подводный камень в том, что syms[0]копия a и имеет другой адрес.Чтобы быть в курсе этого, я, вероятно, мог бы взять на себя ответственность пользователя.

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Может ли адрес объекта меняться во время выполнения программы?

Нет.Адрес объекта никогда не изменяется.

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

Пример:

std::map<CustomClass*,double> map;
{
    CustomClass o;
    map.emplace(&o, 3.14);
}
// the pointer within the map is now dangling; the pointed object does not exist

Также обратите внимание, что некоторые операции над поступающими контейнерами приводят к тому, что элементы контейнера занимают новый объект, а старые уничтожаются.После такой операции ссылки (в общем смысле, включая указатели и итераторы) на эти элементы недопустимы, и поведение попытки доступа через эти ссылки не определено.

0 голосов
/ 18 февраля 2019

Объекты никогда не меняют адрес в течение своей жизни.Если все, что вы хотите сделать, это найти какое-либо значение, связанное с объектом, адрес которого известен во время поиска, то использование адреса объекта в качестве ключа на карте должно быть совершенно безопасным.

(Это даже безопасно, если объект был уничтожен и / или освобожден, если вы не разыменовываете указатель и используете его только как ключ для поиска элемента на карте. Но вы можете выяснить, какудалить записи с карты, когда объекты уничтожены или по другим причинам больше не должны быть на карте ...)

...