-2
struct A
{
     union 
    {
       int array[10];

    struct 
        {
        int a1;
        int a2;
        ...
        ...
        int a10;
        };

};

A a; //1 - structure defination
a.array[0] = 10 //2 - then a.a1 is also assigned with value 10. so how does memory is created.

A *a = new A;
delete a;// does compiler takes care of deleting union and struct members inside struct ? 

Came across this snippet of code online, can anyone explains how memory is created for the above struct because when a value is assigned to union of array then it gets assigned to inner struct variables.

I think initially innermost will Struct gets created with memory separately for each member, how does memory is cerated for union.union creates a single block with the 10*double size but hows does mapping is created between inner union and struct.

  • _"The union is only as big as necessary to hold its largest data member. The other data members are allocated in the same bytes as part of that largest member. The details of that allocation are __implementation-defined__... "_ source: https://en.cppreference.com/w/cpp/language/union – Richard Critten Dec 18 '19 at 12:21
  • 1
    What do you mean by "memory is created"? Do you mean "how is this struct laid out in memory?" Please try use standard terminology. – Botje Dec 18 '19 at 12:22
  • Wrong intuition: memory is not created, just allocated. And you need to read a good C++ programming book, like [this one](http://stroustrup.com/Programming/). Later read some C++ standard, like [n3337](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf). We cannot teach you C++ in a few paragraphs. – Basile Starynkevitch Dec 18 '19 at 12:22
  • https://en.cppreference.com/w/cpp/language/union – Basile Starynkevitch Dec 18 '19 at 12:38
  • https://stackoverflow.com/a/2902171/17034 – Hans Passant Dec 18 '19 at 14:44

2 Answers2

1

When declaring a union. all the union's variables coincide in memory (occupy the same space).

In your example, the array and the struct exist on the same exact memory space. so setting array[0] will overwrite a1. array[1] will overwrite a2 and so on...

Lior
  • 284
  • 1
  • 6
1

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…

Michael Kenzel
  • 15,508
  • 2
  • 30
  • 39