Consider the following ANSI C program: #include<stdio.h> #include<stdlib.h>…

2025

Consider the following ANSI C program:

#include<stdio.h>
#include<stdlib.h>
struct Node {
  int value;
  struct Node *next;
};
int main() {
  struct Node *boxE, *head, *boxN;
  int index = 0;
  boxE = head = (struct Node *) malloc(sizeof(struct Node));
  head->value = index;
  for (index = 1; index <= 3; index++) {
    boxN = (struct Node *) malloc(sizeof(struct Node));
    boxE->next = boxN;
    boxN->value = index;
    boxE = boxN;
  }
  for (index = 0; index <= 3; index++) {
    printf("Value at index %d is %d\n", index, head->value);
    head = head->next;
    printf("Value at index %d is %d\n", index + 1, head->value);
  }
}

Which one of the following statements is correct about the program?

  1. A.

    Upon execution, the program creates a linked-list of five nodes

  2. B.

    Upon execution, the program goes into an infinite loop

  3. C.

    It has a missing return which will be reported as an error by the compiler

  4. D.

    It dereferences an uninitialized pointer that may result in a run-time error

Attempted by 17 students.

Show answer & explanation

Correct answer: D

Concept

malloc() only reserves raw memory for a struct -- it does not zero-initialize any field. So after struct Node *p = malloc(sizeof(struct Node)), every member of *p, including next, holds indeterminate (garbage) memory until the program explicitly assigns it. Dereferencing such an unassigned pointer is undefined behaviour in C: the standard gives no guarantee about what happens, but in practice it commonly surfaces as a run-time crash rather than any compile-time diagnostic.

Application

  1. Before the first loop, one node is allocated and both boxE and head are set to point to it; its value is set to index (0). Call this node0.

  2. The first for loop runs for index = 1, 2, 3 -- exactly three iterations. Each iteration allocates a new node, links the previous node's next to it, stores value = index, and advances boxE to the new node. This produces node1 (value 1), node2 (value 2), and node3 (value 3), giving a list of exactly four nodes: head -> node0(0) -> node1(1) -> node2(2) -> node3(3).

  3. Crucially, node3's next field is never assigned anywhere in the program -- it still holds whatever garbage value malloc returned.

  4. The second for loop runs index = 0, 1, 2, 3 (four iterations). Each iteration prints head->value, then does head = head->next, then prints head->value again. Tracing it: at index 0, prints node0(0), moves to node1, prints node1(1); at index 1, prints node1(1), moves to node2, prints node2(2); at index 2, prints node2(2), moves to node3, prints node3(3).

  5. At index 3, the loop prints node3(3), then executes head = head->next -- but node3->next was never assigned, so head now holds the garbage address from the earlier step. The very next line, printf(..., head->value), dereferences that garbage pointer.

Cross-check

  • Exactly four nodes are allocated (one before the loop plus three inside it, since the loop body executes only for index = 1 to 3) -- not five.

  • Both loops have fixed starting values, increments, and bounds (1 to 3, and 0 to 3), so each runs a set number of times and terminates -- there is no infinite loop.

  • main() reaching its closing brace without an explicit return is, at worst, something most ANSI C compilers flag with a warning, not a fatal compilation error -- the program still builds.

  • The one behaviour the trace above actually forces is dereferencing node3's unassigned next pointer -- undefined behaviour that is unsafe at run time and that the C standard does not require any compiler to diagnose, unlike the other three claims.

Explore the full course: Lti Mindtree Preparation

Loading lesson…