Compose the ownership discipline into one structure — a stack of owned
strings with full lifecycle:
``c
typedef struct { char **items; size_t len, cap; } StrStack; /* in boilerplate */
void ss_init(StrStack *s);
/* pushes a COPY of s. 0 on failure; stack unchanged then. */
int ss_push(StrStack *s, const char *s2);
/* pops: hands the TOP string's ownership back to the caller and removes it.
Returns the pointer (caller now owns and must free), or NULL if empty. */
char *ss_pop(StrStack *s);
/* peeks without transferring: the stack still owns it */
const char *ss_peek(const StrStack *s);
/* frees everything; safe to call twice */
void ss_destroy(StrStack *s);
``
Difficulty: intermediate