#define _GNU_SOURCE #include #include #include #include "person_v1.h" // It's often useful to separate the notions of "allocate space" from "initialize." // We do that here. // // On success, this method returns the Person pointer it was passed. // On failure, it returns NULL. // // The 'static' here makes the scope of '_person_init' just the rest of // this file (i.e., not global scope). // There is a convention in many languages to use names that begin with one // or more underscores to indicate the method should be considered "private". static Person *_person_init(Person *p, const char *name) { p->name = strdup(name); if ( p->name == NULL ) return NULL; return p; } Person *person_new(const char *name) { if (name == NULL) { return NULL; } Person *p = malloc(sizeof(Person)); if (!p) { return NULL; } if ( _person_init(p, name) == NULL ) { free(p); return NULL; } return p; } // Returns 0 on success, -1 on failure. int person_delete(Person *p) { if ( p == NULL) return -1; free(p->name); // free() works even if its argument is NULL p->name = NULL; // Not really necessary, but a good habit... free(p); return 0; // Assume it always works :) } const char *person_get_name(const Person *p) { if ( p == NULL) return NULL; return p->name; } char *person_toString(const Person *p) { char *s = NULL; if (p==NULL) return NULL; if (asprintf(&s, "Name: %s\n", p->name) <= 0) return NULL; return s; }