Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does access a pointer in a union this way cause segmentation fault?

Tags:

c++

g++-5

Why does the following code cause segmentation fault?

#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");
}

I should say that it does not seem to matter if I instead of the return statement try to access the pointer in some other way. E.g. replace delete u.str_ptr; return 0; with return u.str_ptr->compare("A"); I still get a segmentation fault.

In case this is compiler specific I am using g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609

like image 392
Ale Avatar asked Oct 20 '16 10:10

Ale


2 Answers

It is not legal to access u.str_ptr unless it was the last member set in the union. But the last member set in the union is boolean, since an initializer list with one undesignated value sets the first member.

See "member lifetime" under struct and union initialization.

like image 93
David Schwartz Avatar answered Oct 25 '22 06:10

David Schwartz


U u{new std::string("A")}; doesn't make what you think, as you said nothing special it initializes the first member with the value of the call to new. If you want to set the right member use the following:

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

---EDIT---

This is gcc extension, standard says When a union is initialized with a brace-enclosed initializer, the braces shall only contain an initializer-clause for the first non-static data member of the union.. Then with standard you can only do :

U u;
u.str_ptr = new std::string("A");
like image 27
Jean-Baptiste Yunès Avatar answered Oct 25 '22 06:10

Jean-Baptiste Yunès