Code:

#include <stdio.h>
#include <stdlib.h>

struct Student {
    int roll;
    char name[50];
    float marks;
};

int main() {
    int n;
    struct Student *s;

    printf("Enter number of students: ");
    scanf("%d", &n);

    s = (struct Student *)malloc(n * sizeof(struct Student));
    if (s == NULL) {
        printf("Memory allocation failed.\n");
        return 1;
    }

    for (int i = 0; i < n; i++) {
        printf("\nEnter details for student %d:\n", i + 1);
        printf("Roll No: ");
        scanf("%d", &(s + i)->roll);
        printf("Name: ");
        scanf(" %49[^\n]", (s + i)->name);
        printf("Marks: ");
        scanf("%f", &(s + i)->marks);
    }

    printf("\n--- Student Records ---\n");
    for (int i = 0; i < n; i++) {
        printf("Roll No: %d, Name: %s, Marks: %.2f\n", (s + i)->roll, (s + i)->name, (s + i)->marks);
    }

    free(s);
    return 0;
}

Explanation:

Dynamic Memory:
Memory is allocated at runtime using malloc() based on the number of students entered by the user.

Pointer Arithmetic:
The pointer s is used with arithmetic to access each student record: (s + i)->roll, (s + i)->name, etc.

Structure Input and Output:
Inputs are taken directly into the structure fields using pointer dereferencing. A loop displays all student data in a formatted manner.

Memory Deallocation:
free(s) ensures no memory is leaked once the program finishes using the allocated space.