click below
click below
Normal Size Small Size show me how
CIS2500 extra
| Question | Answer |
|---|---|
| What is the difference between stack vs the heap in memory allocation | The stack is automatic and the heap is manual memory handling |
| Describe the stack | Managed automatically by the computer. Data is "local" to functions. Fixed size, relatively small. |
| Describe the heap | Managed by you, the programmer. Data is "global" and persistent. Flexible size, much larger. |
| What are functions used to manage the heap | We use malloc(), calloc(), realloc(), and free() to manage the Heap. |
| what is failure to free memory | a memory leak |
| what happens if you try to malloc but theres no memory left, what if you dont check for null | Segmenation fault when you try to use the null pointer |
| which is correct A) float *p = malloc(50); B) float *p = malloc(sizeof(float) * 50); C) float *p = malloc(sizeof(float) + 50); D) float *p = malloc(sizeof(50)); | B) float *p = malloc(sizeof(float) * 50); |
| what are the differences between calloc and malloc | calloc takes two arguments: the number of items and the size of each item and it clears the memory to zero. |
| if you need to resize memory which function should you use | *realloc(void *ptr, size_t new_size); |
| What is the realloc golden rule/ trap | Never assign the return of realloc() back to your original pointer. |
| What is a stream | A stream is a sequence of bytes. C programs interact with streams via a FILE pointer. |
| What are the 3 streams C automatically opens and what handles them | 1. stdin: Default input (Keyboard). 2. stdout: Default output (Terminal). 3. stderr: Error output (Terminal) We use <stdio.h> to handle these |
| what do these functions do, fprintf, fscanf, fgets | fprintf: Formatted output to a stream. fscanf: Formatted input from a stream. fgets: Reads a whole line safely. |
| What happens if you use the mode "w" on a file that already exists and contains data? | he file is truncated (erased) and overwritten |
| why are binary files preferable | 1. Speed: its faster 2. Precision: Binary stores the exact bits for easy conversion 3. Random Access: every record is the same size 4. Structural Integrity: You can save structs or arrays in a single fwrite call |
| Functions like fread and fwrite are known as | Block I/O. Unlike fprintf, they move data in "blocks" of bytes |
| Why is sizeof critical when using fread or fwrite? | it ensures the correct number of bytes are moved based on the data type, ensuring portability across systems where int or structs might differ in size |
| what do fseek and ftell do | While fseek sets the position, ftell gets the current position |
| How do you determine the total size (in bytes) of a file using fseek and ftell? | fseek to SEEK_END, then call ftell |
| what is the code for factorial in c | int factorial(int n) { if (n == 0) return 1; return n * factorial(n - 1); } |
| What is the call stack | Each call has its own stack frame Stores parameters, locals, return address Deep recursion consumes stack memory |
| What is recursion vs iteration | Recursion: uses stack memory, risk of overflow Iteration: faster, constant memory, safer for deep loops |
| What is tail recursion | A function is tail recursive if the recursive call is the very last action performed by the function. No calculation is performed on the returned value of the recursive call |
| What are issues with call stack | When a function is called, specific data (return address, local variables, parameters) is pushed onto the stack. In standard recursion, the stack grows with the depth of the calls (O(n) depth). |
| Memoization definition | An optimization technique where we store (cache) the results of expensive function calls and return the cached result when the same inputs occur again |
| What does tail recursion use | Uses accumulators to pass state forward. Allows the compiler (or manual goto optimization) to reuse stack frames, behaving like a loop |
| What does Memoization use | Uses persistent storage (like static arrays) to remember previous results, reducing time complexity from Exponential O(2n) to Linear O(n) |
| What is the array bottleneck | Imagine an array of 400 students. To add one student at index 0, you must move 400 integers one step to the right |
| What are some common dynamic data structures | Linked lists, stacks (LIFO), Queues (FIFO), Trees, Graphs |
| Why is inserting an element into the middle of a large array inefficient compared to a linked list? | You must shift all subsequent elements to make room |
| A node is what type of structure | self-referential structure. ▶ It contains data (int, char, struct, etc.). ▶ It contains a pointer to the next Node. |
| To manage a list we only need to know one thing.. | The head where it starts |
| When working with a linked list what should you be careful of | Never move the actual head pointer during traversal, or you will lose the start of your list! |
| If you lose the head pointer of a singly linked list, what happens to the rest of the nodes? | they remain in memory but are unreachable (Memory Leak) |
| Explain the difference between a "Self-Referential Structure" and a standard structure | A self-referential structure contains a pointer to its own type. Standard structures do not |
| Given a pointer to the head of a list, write a code snippet to delete the first node | Node *tempNode = head; if (head != NULL) { head = head->next; free(tempNode); } |
| Why does add_to_list(Node **list, int n) require a double pointer (**)? | To modify the address stored in the head pointer in the calling function (e.g., main). If we pass a single pointer, we only modify a copy of that address. |
| Trace: (10, 20, 30). You perform: head->next->next->next = head; What type of list is this? | Circular Linked List |
| Draw the state of memory after: 1. head = malloc(...); head->data = 5; 2. head->next = malloc(...); head->next->data = 10; 3. free(head); Is there a memory leak? | Yes. Freeing head orphans the second node (10). The pointer to the second node was inside the first node, which is now gone. |
| What are advantages to doubly linked lists | Bi-directional traversal, efficient deletion, easier reversal, navigation |
| What is an Abstract data type (ADT) | A high-level description of a data structure and the operations that can be performed on it., It focuses on what the data structure does, rather than how it is implemented, Separation of Interface (header file) from Implementation (source file) |
| The queue core operations | enqueue(item): Add an item to the rear. dequeue(): Remove and return the front item. front(): Examine the front item without removing it. isEmpty(): Check if the queue is empty. |
| In a Queue what happens if the last element is removed | both front and rear must be set to NULL |
| Where are functions in memory | Text segment |
| What is a callback | a function passed to another function and executed later. |
| What are common uses of callback | ▶ event-driven systems ▶ library customization ▶ algorithm selection ▶ user-defined logic |
| what does the call decide with call backs | The caller decides what behaviour to inject. |
| What are jump tables | Arrays of function pointers provide O(1) algorithm selection |
| What is a tree | A Tree is a hierarchical data structure consisting of nodes connected by edges |
| what are the different tree traversals (visiting each node once) | In-order: Left Subtree → Root → Right Subtree Pre-order: Root → Left Subtree → Right Subtree Post-order: Left Subtree → Right Subtree → Root |
| When deleteing a tree never free a node until... | its children are gone. |
| What is a Binary search tree | a node based tree with, left subtree with only nodes less than key,right subtree with only nodes greater than |
| Why Use a Binary Search Tree (BST)? | A BST provides a balance, allowing for Search, Insertion, and Deletion in O(h) time (where h is the height of the tree) |