Last active
November 5, 2018 16:06
-
-
Save icholy/3c605ae747397c156a80a8837c103801 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// we want to write a constructor function | |
// for this structure | |
typedef struct { | |
char* bar; | |
char* baz; | |
size_t baz_len; | |
} Foo; | |
// This the first approach. When an allocation fails, we | |
// free all the previously allocated memory before returning NULL | |
*Foo foo_new_1(size_t len) { | |
Foo* foo = (*Foo)malloc(sizeof(Foo)); | |
if (foo == NULL) { | |
return NULL; | |
} | |
foo->bar = (char*)malloc(sizeof(char)*20); | |
if (foo->bar == NULL) { | |
free(foo); | |
return NULL; | |
} | |
strcpy(foo->bar, "hello world"); | |
foo->baz_len = len; | |
foo->baz = (char*)malloc(sizeof(char)*len); | |
if (foo->baz == NULL) { | |
free(foo->bar); | |
free(foo); | |
return NULL; | |
} | |
return foo; | |
} | |
// This does the same thing as above, but shares | |
// some of the cleanup code | |
*Foo foo_new_2(size_t len) { | |
Foo* foo = (*Foo)malloc(sizeof(Foo)); | |
if (foo == NULL) { | |
goto cleanup_1; | |
} | |
foo->bar = (char*)malloc(sizeof(char)*20); | |
if (foo->bar == NULL) { | |
goto cleanup_2; | |
} | |
strcpy(foo->bar, "hello world"); | |
foo->baz_len = len; | |
foo->baz = (char*)malloc(sizeof(char)*len); | |
if (foo->baz == NULL) { | |
goto cleanup_3; | |
} | |
return foo; | |
cleanup_3: | |
free(foo->baz); | |
cleanup_2: | |
free(foo); | |
cleanup_1: | |
return NULL; | |
} | |
// the final method just treats an allocation failure | |
// as a fatal error | |
void* must_malloc(size_t size) { | |
void* p = malloc(size); | |
if (p == NULL) { | |
fprintf(stderr, "out of memory"); | |
exit(EXIT_ERROR); | |
} | |
return p; | |
} | |
// sooo much simpler | |
*Foo foo_new_3(size_t len) { | |
Foo* foo = (*Foo)must_malloc(sizeof(Foo)); | |
foo->bar = (char*)must_malloc(sizeof(char)*20); | |
strcpy(foo->bar, "hello world"); | |
foo->baz_len = len; | |
foo->baz = (char*)must_malloc(sizeof(char)*len); | |
return foo; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment