Last active
August 29, 2017 14:12
-
-
Save wortelstoemp/6b29d7cb00d677250df28016630e753e to your computer and use it in GitHub Desktop.
Memory management in C. This is probably the only use-case I've encountered where usage of the keyword "goto" actually simplifies a lot of code and headaches concerning memory management in C. I use "malloc" and the corresponding "free" in the same function. I don't know if there are better ways to do this without overcomplicating it.
This file contains hidden or 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
| #include <stdio.h> | |
| #include <string.h> | |
| int foo(void) | |
| { | |
| /* Declarations and allocations */ | |
| int result = 0; | |
| char *buffer1 = (char *)malloc(100 * sizeof(char)); | |
| int *buffer2 = (int *)malloc(100 * sizeof(int)); | |
| float *buffer3 = (float *)malloc(100 * sizeof(float)); | |
| int condition = 0; | |
| memset(buffer1, 0, 100 * sizeof(char)); | |
| memset(buffer2, 0, 100 * sizeof(int)); | |
| memset(buffer3, 0, 100 * sizeof(float)); | |
| /* Some code */ | |
| /* ... */ | |
| if (condition) { | |
| /* Do stuff */ | |
| result = 42; | |
| goto return_section; | |
| } else { | |
| /* Do other stuff */ | |
| result = 1; | |
| goto return_section; | |
| } | |
| return_section: | |
| { | |
| /* Clean-up (only of memory allocated by malloc in current function) */ | |
| /* De-allocations in opposite order of allocations */ | |
| free(buffer3); | |
| free(buffer2); | |
| free(buffer1); | |
| return result; | |
| } | |
| } | |
| int bar(int *external_buffer, const size_t external_buffer_count) | |
| { | |
| /* Declarations and allocations */ | |
| int result = 0; | |
| char *buffer1 = (char *)malloc(100 * sizeof(char)); | |
| int *buffer2 = (int *)malloc(100 * sizeof(int)); | |
| float *buffer3 = (float *)malloc(100 * sizeof(float)); | |
| int i = 0; | |
| int condition = 0; | |
| memset(buffer1, 0, 100 * sizeof(char)); | |
| memset(buffer2, 0, 100 * sizeof(int)); | |
| memset(buffer3, 0, 100 * sizeof(float)); | |
| /* Some code */ | |
| /* ... */ | |
| for (i = 0; i < external_buffer_count; i++) { | |
| external_buffer[i] = 1; | |
| } | |
| if (condition) { | |
| /* Do stuff */ | |
| result = 42; | |
| goto return_section; | |
| } else { | |
| /* Do other stuff */ | |
| result = 1; | |
| goto return_section; | |
| } | |
| return_section: | |
| { | |
| /* Clean-up (only of memory allocated by malloc in current function) */ | |
| /* De-allocations in opposite order of allocations */ | |
| free(buffer3); | |
| free(buffer2); | |
| free(buffer1); | |
| return result; | |
| } | |
| } | |
| int main(void) | |
| { | |
| int result = 0; | |
| int x = 0; | |
| int y = 0; | |
| const size_t external_buffer_count = 100; | |
| int *external_buffer = (int *) malloc(external_buffer_count * sizeof(int)); | |
| const size_t other_buffer_count = 200; | |
| int *other_buffer = (int *) malloc(other_buffer_count * sizeof(int)); | |
| int error_condition = 0; | |
| memset(external_buffer, 0, external_buffer_count); | |
| memset(other_buffer, 0, other_buffer_count); | |
| x = foo(); | |
| y = bar(external_buffer, external_buffer_count); | |
| printf("x: %d\ny: %d\ne: %d\n", x, y, external_buffer[0]); | |
| /* Lets say I want to free this memory earlier because I don't need it anymore */ | |
| /* Set pointer to NULL: prevents double freeing when entering return_section */ | |
| free(external_buffer); | |
| external_buffer = NULL; | |
| /* Doing other stuff but it inflicts an error */ | |
| /* ... */ | |
| error_condition = 1; | |
| if (error_condition) { | |
| printf("Error!\n"); | |
| goto return_section; | |
| } | |
| /* Doing other stuff with other_buffer */ | |
| /* ... */ | |
| x = 0; | |
| return_section: | |
| { | |
| /* De-allocations in opposite order of allocations */ | |
| free(other_buffer); | |
| free(external_buffer); | |
| return result; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment