словарь — c ++ STL map :: operator [] сделано для удаляемой записи

std::map<int,int> bar;

int foo(int key)
{
bar.erase(key);
return 1;
}

int main()
{
bar[0] = foo(0);
return 0;
}

Этот код, скомпилированный с GCC 4.8, вызывает ошибку при проверке использования памяти с помощью электрического ограждения.

LD_PRELOAD=libefence.so.0.0 ./a.out

Проблема заключается в том, что компилятор генерирует код, который начинает выделять новую запись на карте, а затем выполняет foo() чтобы получить значение, чтобы положить в bar[0], Во время бега foo()запись уничтожается, и код в конце концов заканчивается записью в нераспределенной памяти.

Зависит ли порядок упорядочения операций от реализации компилятора или он определен текущим стандартом C ++?

5

Решение

Стандарт (§1.9 15) указывает, что вычисление двух операндов для бинарного оператора не секвенировано (если только в некоторых конкретных случаях):

Если не указано иное, оценки операндов отдельных операторов
и подвыражений отдельных выражений не упорядочены.

Это означает, что он не требует, чтобы одна сторона операции присваивания была оценена перед другой, и фактически это неопределенное поведение, зависящее от порядка этих непоследовательных операций.

Это также в целом верно для порядка вычисления аргументов функции.

Вы должны разбить свое назначение на две части:

int result = foo(0);
bar[0] = result;
5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]