Почему доступ к указателю в объединении таким образом вызывает ошибку сегментации?

Почему следующий код вызывает ошибку сегментации?

#include <string>

union U {
    bool boolean;
    double number;
    std::string* str_ptr;
};

int main()
{
    U u{new std::string("A")};
    delete u.str_ptr;
    return 0;
    // return u.str_ptr->compare("A");
}

Я должен сказать, что не имеет значения, пытаюсь ли я вместо оператора return получить доступ к указателю каким-либо другим способом. Например заменить delete u.str_ptr; return 0; с return u.str_ptr->compare("A"); Я все еще получаю ошибку сегментации.

В случае, если это зависит от конкретного компилятора, я использую g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609

3 ответа

Решение

Доступ запрещен u.str_ptr если это не был последний член, установленный в союзе. Но последний член в союзе boolean, поскольку список инициализаторов с одним неуказанным значением устанавливает первый член.

Смотрите "время жизни члена" в разделе " Инициализация структуры и объединения".

U u{new std::string("A")}; не делает то, что вы думаете, как вы сказали ничего особенного, он инициализирует первый член со значением вызова new, Если вы хотите установить правильный член, используйте следующее:

U u{.str_ptr=new std::string("A")};

---РЕДАКТИРОВАТЬ---

Это gcc расширение говорит стандарт, когда объединение инициализируется инициализатором, заключенным в фигурные скобки, фигурные скобки должны содержать предложение инициализатора только для первого не статического члена данных объединения., Тогда со стандартным вы можете сделать только:

U u;
u.str_ptr = new std::string("A");

Указатель, возвращаемый функцией new, неявно преобразуется в тип первого члена, т.е. bool, Поскольку C++ допускает это преобразование, ошибки не возникает.

// effectively what is happening.
U u{ new std::string("A") != 0 };

При использовании подобного объединения, вероятно, лучше быть явным и присваивать его членам напрямую. Но если вы действительно хотите сделать это так, просто сделайте str_ptr первый член.

Другие вопросы по тегам