While a struct places its members next to each other, a union essentially overlays its members on top of each other. Of the members of a struct, all can be alive at the same time. Of the members of a union, at most one can be alive at any point in time. The value of a struct can be any combination of values of its members. The value of a union, on the other hand, can only be the value of one of its members. A union
is useful in cases where you need to keep only one of a set of different kinds of values at a time.
In your particular example, the union inside struct A
essentially overlays the member array
, which is an array of ten int
, with an anonymous struct that has ten members of type int
(note, anonymous structs are non-standard but supported by most compilers). It does so, presumably, to be able to access the members of the struct either by their name or, through the array, by their "index". The memory layout of an array of ten int
and of a struct with ten members of type int
will usually be such that consecutive members of the struct will end up coinciding in memory with consecutive elements of the array. Thus, this will usually "work" in practice most of the time.
While this will usually "work" in practice most of the time, it is not correct C++ (hence the ""). By assigning to an element of the array, you begin the lifetime of that union member [class.union]/5. Beginning the lifetime of that union member ends the lifetime of any other union member that may have been alive before [basic.life]/1. This means that the moment you assign something to an element of the array, the struct is no longer alive. And the moment you assign something to a member of the struct, the array is no longer alive. Attempting to access a member of the struct while the array is alive, or attempting to access an element of the array while the struct is alive results in undefiend behavior (because you're attempting to access the value of an object that does not exist in a way not subject to any exception that would explicitly allow you to do so [class.mem]/23). Don't do this, it's simply wrong.
The memory for an A
is "created" like that for any other struct. You create an object of the particular type. Doing so will either allocate storage for the object automatically or require that you did so manually before you would even be able to create an object in the first place. The non-static data members of your struct A
are subobjects of the struct. They are part of the struct object. When the complete A
object gets destroyed and the memory allocated for it is released, the non-static data members are also destroyed and the memory is released since it was part of the memory allocated for the complete object…