-6

Hi I got this C++ code on a test and the question was "What is the output"

struct Element {
string name;
Element* next;
};      
Element *e1, *e2;
e1 = new Element ();
e2 = new Element ();    
e1->name = "I am e1 ";
e2->name = "I am e2 ";  
e1->next = e2;
e2->next = e1;  
e1=e2;  
cout << e1->name << e1->next->name;

I am cunfused about the code really. They used a struct, then declared 2 pointers (*e1 and *e2) and then created 2 objects with new Element. Please someone can explain what is going on here?

Element *e1, *e2;
e1 = new Element ();
e2 = new Element ();

Thank you for your help

  • `struct` and `class` are basically the same. The only difference is the default visibility: For `struct` it's `public`, while for `class` it's `private`. – Some programmer dude Sep 19 '22 at 07:54
  • Which part confused you, structs, pointers, new? That's a lot of ground to cover. The code overall is an example of using dynamic memory allocation to create a linked list. Not very good code, but that's presumably beside the point. – john Sep 19 '22 at 07:55
  • 1
    For the three lines of code you highlighted, you describe pretty well what is going on (declared two pointers, created two objects etc.) so I'm still a bit confused about what exactly it is that you don't understand. – john Sep 19 '22 at 07:59
  • I don't understand the new word. e1 and e2 are pointers to a struct Element right? otherwise (if they were Element) they will be definded between struct {} and ; but then it seems they are created and that they are initialized on their vlaues like objects from the Element class or something like that – Ponghines Sep 19 '22 at 08:20
  • 3
    It seems you might need to invest in [some good C++ books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282). – Some programmer dude Sep 19 '22 at 08:23
  • 1
    @Ponghines `new` is for dynamic memory allocation. It creates objects which have indefinite lifetime. To be specific, objects created with `new` are only destroyed when you use `delete` on a pointer to that object. This is a **huge** and important topic in C++, so there is far too much to explain here. Consult your favourite C++ book. It should have several chapters on this. – john Sep 19 '22 at 08:23

1 Answers1

0

At first

Element* e1, e2;

declare two pointers, then following the creation of two elements with new (on the heap):

e1 = new Element();
e2 = new Element();    

which are at the same time assigned to pointers. From now on best try to draw on paper what's going on...

After the assignment, the situation presents itself as:

          --------
[e1] ->  | [next] +->  <yet invalid!>
          --------
          --------
[e2] ->  | [next] +->  <yet invalid!>
          --------

with [...] indicating the pointers and the arrows the targets. Skipping the names entirely, as likely not relevant.

e1->next = e2;

leads to:

          --------
[e1] ->  | [next] | 
          ---|----
             v
          --------
[e2] ->  | [next] +->  <yet invalid!>
          --------

then

e2->next = e1;  

to

          --------
[e1] ->  | [next] | 
          --|----
            v  ^
          -----|--
[e2] ->  | [next] +->  <yet invalid!>
          --------

and finally

e1 = e2;

results in

          --------
[e1] -   | [next] | 
      |   --|----
      |     v  ^
      ->  -----|--
[e1] --> | [next] +->  <yet invalid!>
          --------

Note how two pointers now keep the address of the same data object, while the other one can be accessed via the first one's next pointer.

Note, too, that the code as presented results in two memory leaks as the two objects created with new are never deleted again.

Edit: About new:

new SomeType (optionally with parentheses which then contains, if need be, the parameters you wish to pass to the type's constructor) is a special operation with in C++; it does several things:

  1. It allocates sufficient memory for the object that shall be constructed. The type identifier (SomeType) provides the information for which type memory shall be allocated (in your question for an ojbect of type Element which needs to be able to hold the memory a std::string requires and additionally a pointer).In case this allocation fails, an exception of type std::bad_alloc is thrown (unless you use the special no-throw variant – now going into detail on, though).
  2. It calls the constructor providing to it the address of the memory allocated just before; the constructor does the necessary initalisation as defined (in your case there's a default constructor initialising an empty string and actually not doing anything to the pointer, which is why it remains invalid).
  3. Returns the memory address, which is what makes the assignment to a pointer possible at all.

These are the very basics of the language, any good C++ book should explain them just as well.

Be aware, though, that in modern C++ you'd prefer smart pointers over raw pointers, relieving you from manual memory management (mainly from the need to call delete explicitly).

Aconcagua
  • 24,880
  • 4
  • 34
  • 59
  • I got the second half but stil don't understand if Element object created with new are related to the struct (like a class?) and how they could be assigned to pointers (they are not addresses...) – Ponghines Sep 19 '22 at 08:38
  • @Ponghines `new` returns a pointer to the newly created object. – Miles Budnek Sep 19 '22 at 08:46
  • e1 then points to the first Element object created, so I must fill it with data and later access its data using -> and in the final cout e1->next is another pointer so I must again use -> right? – Ponghines Sep 19 '22 at 09:27
  • Indeed. Both e1 and e1->next are pointers. To get the pointed object you need to dereference via asterisk (`*e1` is the actual object) and can then access its members via a period (`(*e1).name`). Finally there's syntactic sugar for, `e1->name` is short hand for `(*e1).name`, just as the index operator `a[x]` for pointers is just short for `*(a + x)` (but can be overloaded in C++). You can easily identify pointers by the asterisk at their declaration/definition (`Element` **`*`** – though sometimes some unlucky programmers hide it behind a typedef). – Aconcagua Sep 19 '22 at 09:52