So I am looking at a past exam paper which I am studying for my exams coming up and I am really confused regarding this question, can someone give details on the state of the memory for the following:

class Q2 {
   private static int num = 0;
   private String prefix;

   public Q2 (String p)
    { prefix = p; }

   public String Msg (String str) {
      String n;
      num++;   
      n = num.ToString();
     return n + ” - ” + prefix + str;
   }
}

Using an appropriate diagram, describe the state of memory after all of the following statements have been executed.

Q2 var1, var2;
   var1 = new Q2(“Question 2 ”);
   var2 = new Q2 (“Another view ”);

Now consider the method call.

… var1.Msg (“hello again”) …

Explain in detail the following aspects of the execution of this statement; use diagrams where appropriate.

The referencing and calling of the method.
The execution and return of the method.

Discuss the memory management issues that will arise with the following infinite loop.

while (true) {
      Var1 = new Q2 (“Part c ”);
      String s = Var1.Msg (“round and round”);
      … … …
   }

I have been trying to draw diagrams to represent the stack and heap for this example, but I am confused due to the way the objects are created, I appreciate any help on this.

Thanks.

Dani AI

Generated

As correctly pointed out, the important distinction is where data lives (type-level vs instance-level). The clearest exam answer draws three regions and shows what each name actually references: a small type/static area for class data, the managed heap for objects and non-primitive heap allocations, and the call stack for local references and activation records. A precise step-by-step call sequence and an explicit diagram avoid the common mistakes about “stack growth” in the infinite-loop case.

Execution sequence for the call (compact):

  • Evaluate the reference var1 (a local reference on the stack) and push a new activation record for Msg. Inside that frame this points at the Q2 object on the heap and str is the method parameter.
  • num (the class/static cell) is incremented in-place.
  • num.ToString() allocates a new string (a heap object) for n.
  • The concatenation is performed (the C# compiler emits a String.Concat call), producing a single new string result on the heap which is returned.
  • The Msg frame is popped; the caller receives the returned string and stores it in its local s.

Suggested ASCII diagram to include with an answer (draw arrows for pointers):

[TYPE/STATIC]
Q2.num --> 0

[HEAP]
Q2 obj A { prefix --> "Question 2 " (interned) }
Q2 obj B { prefix --> "Another view " (interned) }
"round and round" (literal interned)
"n" and "result" strings (created at runtime)

[STACK - caller]
var1 --> (obj A)
var2 --> (obj B)
... when calling Msg:
  [STACK - Msg frame]
  this --> (obj A)
  str --> (pointer to "hello again")
  local n --> (pointer to ToString result)

Infinite-loop notes and gotchas:

  • Reassigning var1 = new Q2(...) does not push new stack frames each iteration; it only changes the reference stored in that stack slot. The previous heap object becomes eligible for garbage collection (GC) if not referenced elsewhere.
  • The GC reclaims unreferenced objects lazily; a tight allocation loop can cause sustained GC activity, increased memory pressure, and ultimately an OutOfMemoryException if allocation outpaces reclamation or objects are accidentally retained (event handlers, static lists, finalizers, or explicit interning).
  • num++ is not thread-safe; concurrent calls produce a race unless synchronized (e.g., Interlocked.Increment).

For the exam diagram, label arrows (references), show the static cell for num, show interned literals separately, and mark which heap objects are reachable vs eligible for GC after each step.

You must understand that the class Q2 has 2 parts
1) The static part is shared between al the instances of the class
2) The non static part, is owned exclusively by the instance

In this class, the static part is represented by the private static int num initialized by default to 0. Each time is executed the sentence num++; the value is incremented and is visible for each instance.

The non static part is represented by the private string prefix; .
This will mean that each instance will have his own prefix, wich is loaded during the class instantiation new Q2("Question 2") or Q2 (“Another view ”) .

After doing the

Q2 var1, var2;
var1 = new Q2(“Question 2 ”);
var2 = new Q2 (“Another view ”);

you have a unique num variable, with a value of 0, and two prefix variables (one for var1 and another for var2) with the "Question 2" and the "Another view" texts.

Each call of the var1.Msg() function, will increase the value of num by 1. Then will return a string containing the current value of the num variebla, a - sign, the prefix value for the current instance and the string passed to the Msg function.

The infinite loop has the trick that always use the same naming for the instance, but is creating a new instance each time, so the stack vill increase having as many instances as iterations done, and the num value will increase also by 1 at each Msg call.

Hope this helps

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.