My question is regarding freeing allocated memory in different functions. So my code is structured something like this:
int main()
{
// Declare variables
double *val1, *val2;
// Call function 1
function1(&val);
// Call function 2
function2(&val2);
// Do some stuff .....
// Free dynamically allocated memory
free(val1);
free(val2);
// End program
return 0;
}
void function1(double *val1)
{
/* Allocate memory */
val1 = (double*) malloc(n1*sizeof(double));
if (val1 == NULL){
printf("Error: Memory not allocated!");
exit(0);
}
}
void function2(double *val2)
{
// Allocate memory
val2 = (double*) malloc(n2*sizeof(double));
if (val2== NULL){
printf("Error: Memory not allocated!");
// Here I want to free val1!
exit(0);
}
}
Meaning that some memory is allocated for val1 inside function1 and for val2 inside function2.
Now, the contents contained in val1 is not needed in function2, so I would at first sight not have to pass the pointer to val1.
However, if val2 is not allocated correctly I want to exit the program, but free any allocated memory first. Can I free the memory for val1 inside function2 without passing the pointer for val1?
a way to structure functions with dynamic allocation would be to have a return value of an integer, like: int function1(double *val)
that way if it fails you can return a value which would indicate it when the allocation fails, and act accordingly in main()
Can I free the memory for val1 inside function2 without passing the pointer for val1?
No. C language doesn't have a concept of destructors, so commonly used in other languages. In C you have to "pick up the trash" yourself - so if you terminate your program it's nice to free all allocated memory. There are many styles of error handling, choose the one you like. I like kernel coding style. A function that terminates a program in case it fails would be very brutal. A return value that lets the user of the function handle the error case would be nicer and more predictible. It's typical (for me) for C functions to return an int with 0 for success and negative value for failure. Your program could look like this:
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
int function1(double **val1)
{
size_t n1 = 10;
*val1 = (double*) malloc(n1 * sizeof(**val1));
if (*val1 == NULL){
return -ENOMEM;
}
return 0;
}
int function2(double **val2)
{
size_t n2 = 20;
*val2 = malloc(n2 * sizeof(double));
if (*val2== NULL){
return -ENOMEM;
}
return 0;
}
int main()
{
int err = 0;
double *val1, *val2;
err = function1(&val1);
if (err) goto ERROR_function1;
err = function2(&val2);
if (err) goto ERROR_function2;
err = do_some_calc(val1, val2);
free(val2);
ERROR_function2:
free(val1);
ERROR_function1:
return err;
}
Note the error in your program - you were passing double** pointers yet your functions expected double* pointer. Parameters are passed to function by value - values of parameters are copied. To modify a value you have to pass a pointer - that includes pointers, so if you want to modify a pointer you have to pass a pointer to a pointer.
You can write this a lot cleaner & fix some bugs by:
Actually returning a pointer to the allocated memory to the caller. See Dynamic memory access only works inside function.
Leave error handling to the caller.
Leave clean-up to the caller.
This is an artificial example overall, but you could for example do like this:
double function1 (void)
{
return malloc(n1*sizeof(double));
}
double function2 (void)
{
return malloc(n2*sizeof(double));
}
void exit_cleanup (double* v1, double* v2)
{
free(v1);
free(v2);
exit(0);
}
int main (void)
{
double* val1 = NULL;
double* val2 = NULL;
// ...
val1 = function1();
if(val1 == NULL) { exit_cleanup(&v1, &v2); }
// ...
val2 = function2();
if(val2 == NULL) { exit_cleanup(&v1, &v2); }
// Do some stuff .....
exit_cleanup(&v1, &v2);
}
This works because both pointers are initialized to NULL and calling free(NULL) is a safe no-op. All error handling and clean-up has been centralized to a single function. No "on error goto" stuff is necessary.
Another rarely used beast is atexit, which is a standard C function which lets you register a number of functions that will get executed just before program termination. Would have worked just fine here - however, you'd need to make the variables file scope for that case, so it isn't ideal.
You will either have to pass the val1 pointer to function2 or to store val1 globally, both being pretty dirty approaches.
What would be a proper way to approach this issue is to return error codes from both of the functions and handle the errors from main (i.e. free any allocated memory that needs to be free'd).
As a side note, &val1 will have the type double **, not double *. Even though here the might work just fine, it is not correct, and might lead to unexpected behaviour. Your functions would need to be changed like this:
void function1(double **val1)
{
/* Allocate memory */
*val1 = malloc(n1*sizeof(double));
if (*val1 == NULL){
printf("Error: Memory not allocated!");
exit(0);
}
}
This will keep the data types pointer depth properly, and signal you any pointer problem earlier.
Related
I'm new to C and trying to figure out how to dispose of the structures, references to which are returned from a function.
For example, this is roughly what I want to do.
typedef struct test_t{
char *test_c;
} test_t;
int testFunc(test_t** output){
test_t* testStruct = malloc(sizeof(testStruct));
char* buf = malloc(sizeof(char) * 5);
strcpy(buf, "test");
testStruct->test_c = buf;
*output = testStruct;
return 0;
}
int main() {
test_t* test;
testFunc(&test);
printf("%s\n",test->test_c);
free(test);
return 0;
}
So in main I get the test struct. After printf (assume that there is some code after wards) I no longer need it and want to deallocate it. But how to do it properly? Should I just deallocate test_c explicitly first? But what if it wasn't allocated?
A structure can be deallocated just like any other pointer. You however have to ensure that all its allocated members are freed before doing so (failing to do so would most likely result in a memory leak of the members of your structure).
typedef struct test_t{
char *test_c;
} test_t;
int testFunc(test_t** output){
test_t* testStruct = malloc(sizeof(testStruct));
char* buf = malloc(sizeof(char) * 5);
strcpy(buf, "test");
testStruct->test_c = buf;
*output = testStruct;
return 0;
}
int main() {
test_t* test;
testFunc(&test);
printf("%s\n",test->test_c);
free(test->test_c);
free(test);
return 0;
}
In case your structure doesn't allocate all of its elements, you can set their pointer to NULL, which once passed to free (3) would be equivalent to doing nothing.
But how to do it properly? Should I just deallocate test_c explicitly first? But what if it wasn't allocated?
Basic rule of thumb: if you write a function that allocates a resource, write a complementary one that deallocates it. So when applied to your example:
void testFree(test_t* toFree) {
free(toFree->test_c);
free(toFree);
}
... and then ...
printf("%s\n",test->test_c);
testFree(test);
If testFree is implemented and exposed along with testFunc, the callers don't need to know your implementation details. The functions themselves, being part of the same library, will make sure the invariants are maintained properly. Should you ever switch allocation schemes, no calling code needs to change. You would just modify testFree to go along with the new testFunc and re-link.
First, you'll need to free the memory you,ve allocated for the char in the struct given that you have initialized it. Otherwise, you'll get an error so before any free instruction you should check whether the pointer that holds the memory position for test_p you're trying to free isn't NULL. Besides, the free instruction should take *test as a parameter instead of test.
You should have a procedure which allocates and initializes an instance of test_t. In C++ or other object-oriented languages this would be a constructor. In C you have to roll your own - something similar to the following:
test_t *create_test_t(char *init_test_c)
{
test_t *tt;
tt = malloc(sizeof(test_t));
if(init_test_c != NULL)
{
tt->test_c = malloc(strlen(init_test_c)+1);
strcpy(tt->test_c, init_test_c);
}
else
tt->test_c = NULL;
}
You'll also want a function to get rid of a test_t instance correctly. Something like:
void destroy_test_t(test_t *tt, bool static)
{
free(tt->test_c);
if(!static)
free(tt);
}
The static parameter is included to control whether tt should or should not be free'd. Obviously you don't want to attempt to free a pointer to a static instance of test_t, in which case you'd pass TRUE for static. For dynamically-allocated instances of test_t, e.g. those created using the create_test_t procedure, you'd pass FALSE for static.
You then use these functions every time you need to create or destroy a test_t.
Best of luck.
Should I just deallocate test_c explicitly first?
Yes, you have to free test_c first, because, if you free test, you will lose the reference to test_c.
But what if it wasn't allocated?
As you are returning int from testFunc, you can use it as a state of the allocation of your structure (although, returning a pointer would be a better idea IMHO):
int testFunc(test_t** output){
test_t* testStruct = malloc(sizeof(testStruct));
if (testStruct == NULL)
/* testStruct allocation failure. */
return -1;
char* buf = malloc(sizeof(char) * 5);
if (buf == NULL) {
/* buf allocation failure. */
free(testStruct);
return -1;
}
strcpy(buf, "test");
testStruct->test_c = buf;
*output = testStruct;
return 0;
}
After that, you check testFunc failure:
/* Check for allocation failure. */
if (testFunc(&test) == -1) {
fprintf(stderr, "Allocation error");
exit(EXIT_FAILURE);
}
/* Allocation succeeded. */
printf("%s\n",test->test_c);
free(test->test_c);
free(test)
If we were to use malloc() in main(), we could free() that dynamic memory allocation in main().
However, if we use malloc() in a different function
and we use that function in main(), where should we call free() to release the memory allocated in that function?
I.e., in the following source code:
#include <stdio.h>
#include <stdlib.h>
int * memory_allocate_function(int);
int main(void) {
int n=5; //length of array, 5 for example.
int *my_array;
my_array = memory_allocate_function(n);
return 0;
}
int * memory_allocate_function(int n) {
int i;
int *array;
array=(int *)malloc(n * sizeof(int));
if(array == NULL) {
printf("can not allocate memory.");
return NULL;
}
// I think i can't use "free(array);" in here.
// Because I need that array in main().
return array;
}
Is this the best way to do this?
Well after you are done working with it - free the dynamically allocated memory. But design wise - you can call the free in other function also to manage it properly. It really depends. There is no hard rule for that.
For example here you should return that pointer to allocated memory and then after using it in main you can free it in main().
So the structure would be something like
int* memory_allocate_function(int n)
{
int i;
int *array;
array = malloc(n*sizeof(int));
if(array == NULL)
{
printf("can not allocate memory.");
exit(0);
}
return array;
}
Then in main()
int main(void)
{
int n=5; //length of array, 5 for example.
int *arr = memory_allocate_function(n);
// work with arr
free(arr);
return 0;
}
But yes name the function properly - if you are going to use the name memory_allocate_function function then do that only - not any other major logic should be there. This helps create a good readable code.
Note one thing - here when you called the function and then you exited the function the only local variable that contains address of it, it's storage duration ended and you can never then access the memory you allocated. This is a case of memory leak. If you are determined that you won't return the pointer to memory from the function - then work with it (in the same function or different) and then free it (Before the scope of the function ends - notice not mentioning about where you would free it, you can do it in the same function and other function also).
I can't help mentioning few things:- 1) Dont cast the return value of malloc. 2) Check the return value of malloc - in case it is NULL you would like to handle it separately. 3) The recommended signature of main() is int main(void)
Memory should be freed when it's no longer needed.
Since the array would no longer be accessible after memory_allocate_function exits (since the array isn't returned or otherwise made accessible to the outside), it should be freed before memory_allocate_function exits.
void memory_allocate_function(int n){
int i;
int *array;
array = malloc(n*sizeof(int));
if (array == NULL) {
fprintf(stderr, "Out of memory.");
exit(1);
}
// ... use the array ...
free(array);
}
If you need to malloc memory in one function and free in another, you have to somehow carefully pass the pointer to that malloced memory from the point of malloc to the point where you want to free it.
This is your responsibility to preserve the pointer value and hand it from one function to another until it reaches the point of free. If you lose that value along the way, you'll have a memory leak. A memory leak is what you have now, since you are not passing that local array pointer anywhere.
There's no "one true way" to do it, since it depends on your specific intent. For example, you can return that pointer from memory_allocate_function, receive it main and eventually free it there
int *memory_allocate_function(int);
int main()
{
int n = 5;
int *arr = memory_allocate_function(n);
...
free(arr);
return 0;
}
int *memory_allocate_function(int n)
{
int *array = malloc(n * sizeof *array);
...
return array;
}
I'm working on a C project (assignment for school). One of the demands is that in case of malloc() failure, the program must free() all allocated memory and exit().
Consider a case where function A() constructs a linked-list and in each iteration it calls to another function, B(). Now, if a malloc failure occured at B(), it must free() the memory it allocated but function A() should do that as well.
Things are getting quite complicated when you have a tree of function calls larger than two.
In my previous project I used a flag to notify a malloc() failure - if a function uses another function which may use malloc(), it has to check the flag right after. It worked, but code got kinda messy.
Is there a neat solution for this problem?
Of course, with "real" applications all memory is de-allocated by the OS, but I guess this demand is pedagogical..
I think the easiest approach is to create a custom allocator (as somebody already noted in a deleted post) to keep track of all your allocations, then do a custom deallocator, use these for all your heap memory needs.
if a malloc fails you have the list of previously allocated blocks at easy reach.
e.g.
(you need to redo this cause it is not effective and should be optimized but shows the principle and only ocular compilation)
typedef struct
{
void* pMemory; /* for the allocated memory */
size_t size; /* for better debugging */
} MemoryBlock;
#define MAXBLOCKS 1000
MemoryBlock myheap[MAXBLOCKS]; // global so zero:ed
static int block = 0;
void* myalloc(size_t size)
{
static int block = 0;
// you should check vs MAXBLOCKS
myheap[block].pMemory = malloc(size);
myheap[block].size = size;
// check if it failed.
if ( myheap[block].pMemory == NULL )
{
for (int i = 0; i < block; ++i)
{
myfree(myheap[i].pMemory);
}
fprintf( stderr, "out of memory\n");
exit(EXIT_FAILURE);
}
else
{
return myheap[block++].pMemory;
}
}
void myfree(void* p)
{
for (int i = 0; i < block; ++i)
{
if ( p == myheap[i].pMemory )
{
free(myheap[i].pMemory);
myheap[i].pMemory = NULL;
return;
}
}
}
Yes. The best (and conventional) way is to initialize every pointer value to zero. Then set it during the malloc() assignment. Ex: myPtr = malloc( 10 );
It will be zero in case of failure, and you check that. And finally, when you go about freeing, you always check the pointer value before calling free():
if ( myPtr != 0 )
free( myPtr );
There is no need for an extra flag.
Are you having issue checking for errors or handling them? If you want info on catching them, use donjuedo's suggestion.
For ideas on freeing memory in the event of error, try one of these two methods:
1) For a uni-directional linked-list, keep a special pointer that points to the head of the list. In your cascading free function, start at the head, capture the next-pointer in a temp variable, free the head, move to the next structure in the list using the temp-pointer, and repeat the process until the next-pointer == 0.
2) For a bi-directional linked-list (my preference) you don't need to keep a special pointer to the head of the list. Assuming you are still at the tail, just capture the previous-pointer into a temp variable, free the tail, move back using the temp-pointer, and repeat the process until the previous-pointer == 0
You could look into the atexit() function, to register code that will be executed when the program terminates. Such code can then check if there is anything that needs to be free()d.
Note that atexit() has no way to unregister. So you need to make sure that you register each cleanup function only once, and that it does the right thing when there is nothing to clean up.
#include <stdlib.h>
#include <stdio.h>
int *ptr1;
char *ptr2;
int clean1_registered, clean2_registered;
void clean1(void)
{
printf("clean1 called\n");
if (ptr1) {
free(ptr1);
ptr1 = NULL;
}
}
void clean2(void)
{
printf("clean2 called\n");
if (ptr2) {
free(ptr2);
ptr2 = NULL;
}
}
void B(void)
{
ptr2 = malloc(100);
if (!clean2_registered) {
atexit(clean2);
}
}
void A(void)
{
ptr1 = malloc(100 * sizeof(int));
if (!clean1_registered) {
atexit(clean1);
}
B();
}
int main(int argc, char **argv)
{
A();
}
I'm a bit of a C newbie, so I'm still trying to get my head fully around when to worry about memory issues.
Suppose I have the following simple program:
#include <stdlib.h>
/* this returns a malloc()'d string */
char *get_str(int whichone);
int main(void)
{
char *s;
if ((s = get_str(0)) == NULL) {
exit(1);
}
/* position 1 */
if ((s = get_str(1)) == NULL) { /* position 2 */
exit(2);
}
return 0;
}
Obviously, this simple of a program has no worries about memory. It allocates a few bytes (for all intents and purposes), and it exits provided our dear function didn't fail.
Now, suppose I am running similar code inside of a looping and fork()ing program. Should I be using free(s) at position 1 since at position 2 I leave the old value behind and assign a new location for the pointer?
Yes. free releases the memory associated with the pointer that is being free'd. Once you reassign s so that it holds a different memory location, you will have lost your opportunity to free the memory associated with the original value of s.
You should definetly free the memory at position 1, because once you reassigned s you lost any chance to do so. And I'd do it one way or another because you can never know when somebody else is instructed to build a fork into your application and he will assume you did everything right.
If you have a pointer to memory that have been allocated using one of the malloc() type calls then when you are done with the memory area, you should deallocate the memory using free(). Similarly using calloc(), which also allocates from the heap, should be followed by the use free() to deallocate the memory when done with it.
The other memory allocator such as alloca() which allocates from the stack and not the heap see On the use and abuse of alloca does not use the free() function and that memory will be recovered automatically as the stack pointers are adjusted when the function in which it is used returns. Naturally that means that using a pointer from alloca() is only good for the function and any functions it calls and the address becomes invalid as soon as the function using alloca() returns.
In your simple example, I would use free() just before the call to the get_str(1) function at position 2 so the source would look something like"
int main(void)
{
char *s;
if ((s = get_str(0)) == NULL) {
exit(1);
}
// doing stuff with the string pointed to by s
/* position 1 */
// free up the string area so that we can get another one.
free (s);
if ((s = get_str(1)) == NULL) { /* position 2 */
exit(2);
}
return 0;
}
I might also be tempted to modify your example a touch and do something like the following. This was all written without testing in a compiler so there may be a compilation error or two however this should provide the basic idea.
The idea with this approach is to have a struct that contains state information as well as a pointer so that you will know which type of get_str() pointer came from, if you are interested, and when you call the get_str() function, it will deallocate the memory for you. You could also add intelligence so that if there is memory already allocated and it is the correct type, then you do not do a free() followed by a malloc() but instead just return back.
Another bonus provided by this approach is when a free() is done, the char * member of the struct is set to NULL which should give you a crash if you try to dereference the pointer and since the whichone member of the struct indicates the last type of get_str() used, your debugging may be easier depending on how good you are with interpreting a crash dump.
#include <stdlib.h>
typedef struct {
int whichone;
char *s;
} GetStrStruct;
/* this returns a malloc()'d string */
GetStrStruct *get_str(int whichone, GetStrStruct *pStruct)
{
free(pStruct->s); // we depend on pStruct->s being valid or NULL here
pStruct->s = NULL;
pStruct->whichone = -1;
switch (whichOne) {
case 0: // allocate string one
pStruct->s = malloc (32); // string one type of memory allocation
pStruct->whichone = whichone;
break;
case 1: // allocate string two
pStruct->s = malloc (64); // string two type of memory allocation
pStruct->whichone = whichone;
break;
default:
break;
}
// if the malloc() failed then return a NULL pointer
// we just reuse the pStruct pointer here, it is local and one less variable to make
if (pStruct->s == NULL) pStruct = NULL;
return pStruct;
}
int main(void)
{
GetStrStruct myStruct = {0}; // create and initialize the struct
if (get_str(0, &myStruct) == NULL) {
exit(1);
}
// do things with myStruct.s, the string from last get_str() call
// this would be using myStruct.s and not just myStruct or s so maybe awkward?
/* position 1 */
if (get_str(1, &myStruct) == NULL) { /* position 2 */
exit(2);
}
// do things with the second type of get_str()
// this would be using myStruct.s and not just myStruct or s so maybe awkward?
// release the memory as I am done. This may seem a bit strange to get a nothing string.
get_str (-1, &myStruct);
return 0;
}
If you added a debug facility you could even track which line of source did the last allocation and the last deallocation. Or if the malloc() fails, you could implement a debugger interrupt or other mechanism to immediately stop so you will know exactly which line the function call failed.
In the include file with the prototype for the get_str() function and the GetStrStruct struct you would use C Preprocessor as follows. If you change the 0 in the #if 0 to a 1 then the debug version is enabled otherwise it is not. The idea is to use a macro through the C Preprocessor to replace calls to get_str() with a call to get_str_Debug() and provide additional arguments with the source file path and the line number in the source file.
#if 0
typedef struct {
int whichone;
char *s;
struct {
int lineNo;
char file[64];
} myDebug;
} GetStrStruct;
GetStrStruct *get_str_Debug(int whichone, GetStrStruct *pStruct, char *file, int line);
#define get_str(wo,ps) get_str_Debug (wo,ps,__FILE__,__LINE__)
#else
typedef struct {
int whichone;
char *s;
} GetStrStruct;
GetStrStruct *get_str(int whichone, GetStrStruct *pStruct);
#endif
And then in the implementation file you could use the C Preprocessor with something like the following to allow you to specify whether the get_str() function should be replaced by a get_str_Debug() function with additional debug aids at compile time.
#if defined(get_str)
// provide a prototype for the replacement function signature.
GetStrStruct *get_str_Special(int whichone, GetStrStruct *pStruct);
// provide the debug information wrapper so that we can track where the last use came from
GetStrStruct *get_str_Debug(int whichone, GetStrStruct *pStruct, char *file, int line)
{
GetStrStruct *pTemp = get_str_Special (whichone, pStruct);
if (pTemp) {
// update the debug information. we keep only last 60 chars of file path.
int iLen = strlen (file);
if (iLen > 60) iLen -= 60; else ilen = 0;
strcpy (pStruct->myDebug.file, file + iLen);
pStruct->myDebug.lineNo = line;
} else {
// cause a debugger interrupt or a crash dump or something.
}
return pTemp;
}
GetStrStruct *get_str_Special (int whichone, GetStrStruct *pStruct)
#else
/* this returns a malloc()'d string */
GetStrStruct *get_str(int whichone, GetStrStruct *pStruct)
#endif
{
free(pStruct->s);
pStruct->s = NULL;
pStruct->whichone = -1;
switch (whichOne) {
case 0: // allocate string one
pStruct->s = malloc (32); // string one type of memory allocation
pStruct->whichone = whichone;
break;
case 1: // allocate string two
pStruct->s = malloc (64); // string two type of memory allocation
pStruct->whichone = whichone;
break;
default:
break;
}
// if the malloc() failed then return a NULL pointer
if (pStruct->s == NULL) pStruct = NULL;
return pStruct;
}
Then where ever you use get_str() if you turn on the debugging, the C Preprocessor will substitute a call to get_str_Debug() with the arguments used in the get_str() call along with two additional arguments, a char pointer to the source file name where the get_str() is being replaced by the get_str_Debug() and the source file line number.
Just for fun (and for C programming practice) I wrote the following piece of code that does the following:
Acts as a tracking system for memory allocations
Frees all dynamically allocated memory with a function call
Here is the code:
typedef enum _OpMode {
OM_APPEND,
OM_DESTROY
} OP_MODE;
void refOp(void *ptr, OP_MODE mode) {
/* contains static array of pointers and provides an interface to that
array */
static void **references = NULL;
static int size = 0;
static int reset = 0;
if (reset) {
reset = 0;
references = NULL;
size = 0;
}
switch (mode) {
case OM_APPEND:
//add a pointer to reference array
references = (void**) realloc(references, sizeof(void*) * (size + 1));
references[size++] = ptr;
break;
case OM_DESTROY:
//free memory at all pointers kept in reference array
for (int i = 0; i < size; i++) {
free(references[i]);
references[i] = NULL;
}
free(references);
reset = 1;
break;
default:
printf("Invalid enum value '%d' passed as mode.\n", mode);
break;
}
}
void refDestroyAll() {
//Wrapper function
refOp(NULL, OM_DESTROY);
}
void *myAlloc(void* ptr, size_t size) {
/* Allocates memory and stores pointer copy in reference array */
void *tmp_ptr;
tmp_ptr = realloc(ptr, size);
refOp(tmp_ptr, OM_APPEND);
return tmp_ptr;
}
The idea is that one would use myAlloc() instead of malloc or realloc to dynamically allocate memory. And one would use refDestroyAll() to free all memory that was created with myAlloc().
I've done some testing, and it seems to be working, but I can't help feeling that I'm missing something important. Does this code actually work as intended, or am I leaking memory when I call refDestroyAll()?
You have a bug, that could cause a segmentation fault. realloc() could return the same pointer as it is given, in which case you would have added it twice to the array. When you call your free function, it would try and free the same pointer twice, resulting in a segmentation fault error.
Additionally, I don't understand why you have the reset parameter. Why not simply set references and size to 0 in the OM_DESTROY case? It is good practice to always set a pointer to NULL immediately after freeing it.