Mentioned above! Design a Stack.
Anonimo
High-Level Memory Layout Each node will be a blob of memory like: [ next pointer ][ user data of variable size ] So: Push allocates a block: sizeof(void*) + size_of_user_data Pop frees that block Top points to the top block’s user data ✅ Design Summary Stack Node: struct StackNode { struct StackNode* next; // Followed by variable-length user data }; We never declare data[] inside the struct. Instead, we allocate extra memory after the struct. ✅ Full Code: Heterogeneous Generic Stack #include #include #include typedef struct StackNode { struct StackNode* next; // Followed by variable-sized data } StackNode; typedef struct { StackNode* top; size_t size; } Stack; // Initialize the stack void stack_init(Stack* s) { s->top = NULL; s->size = 0; } // Push an element of arbitrary size void stack_push(Stack* s, const void* data, size_t data_size) { // Allocate enough for pointer + data StackNode* node = malloc(sizeof(StackNode) + data_size); if (!node) { fprintf(stderr, "Out of memory\n"); exit(1); } // Link to previous top node->next = s->top; s->top = node; s->size++; // Copy the data into the allocated space after the node header void* data_location = (void*)(node + 1); memcpy(data_location, data, data_size); } // Return pointer to the top element’s data void* stack_top(const Stack* s) { if (!s->top) { fprintf(stderr, "stack_top on empty stack\n"); exit(1); } return (void*)(s->top + 1); } // Pop the top element void stack_pop(Stack* s) { if (!s->top) { fprintf(stderr, "stack_pop on empty stack\n"); exit(1); } StackNode* node = s->top; s->top = node->next; free(node); s->size--; } // Check if empty int stack_empty(const Stack* s) { return s->top == NULL; } // Clean up void stack_destroy(Stack* s) { while (!stack_empty(s)) { stack_pop(s); } } ✅ Example Usage c Copy Edit int main() { Stack s; stack_init(&s); int x = 42; double y = 3.1415; const char* msg = "hello"; stack_push(&s, &x, sizeof(x)); stack_push(&s, &y, sizeof(y)); stack_push(&s, msg, strlen(msg) + 1); // include null terminator printf("Top: %s\n", (char*)stack_top(&s)); stack_pop(&s); printf("Top: %f\n", *(double*)stack_top(&s)); stack_pop(&s); printf("Top: %d\n", *(int*)stack_top(&s)); stack_pop(&s); stack_destroy(&s); return 0; } ✅ Output less Copy Edit Top: hello Top: 3.141500 Top: 42 🧠 Why This Is Efficient Only 1 malloc per element No wasted memory for fixed buffer sizes Supports arbitrary types and sizes Stack footprint is minimal: just a pointer to top node