Skip to content

Instantly share code, notes, and snippets.

@wortelstoemp
Last active August 29, 2017 14:12
Show Gist options
  • Select an option

  • Save wortelstoemp/6b29d7cb00d677250df28016630e753e to your computer and use it in GitHub Desktop.

Select an option

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.
#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