how to correctly free a struct? ANSI C - c

How does one correctly free a structure? If I have is this right? Or just called free once is correct?
typedef struct AStruct{
char * buffer;
int size;
} AStruct;
typedef struct S_Session {
int Id;
AStruct* buff;
char * name;
} S_Session;
S_Session* S_Session_new() {
S_Session* s = (S_Session*)malloc(sizeof(S_Session));
s->Id = 1;
s->buff = (AStruct*)malloc(sizeof(AStruct));
s->buff->buffer = malloc(8196);
s->buff->size = 8196;
s->name = malloc(100);
return s;
}
int main(int argc, char *argv[])
{
S_Session* sess = S_Session_new();
free(sess->buff->buffer);
free(sess->buff);
free(sess->name);
free(sess);
}

The rule like others have already said is to free everything you allocate, so from your code, you have 4 malloc's and you call free for those mallocs when the programs ends, which is correct.
In C nothing is automatic, so if you decided to call free only over your allocated struct, the remaining memory that you allocated would not been freed.
But for just a simple program, after the program ends the process is killed and the memory is freed by the Operating System, so it would be the end of the world if your release just the struct.
As a good practice you should free all the allocate memory by your program before it's termination.

In C, you should not cast the return value of malloc(). It can mask an error in the case that the prototype is missing, and the worst case result of using that value may be a crash.
In general, you should check the validity of a function call result before acting upon it. In this case, checking to see if malloc() actually succeeds will avoid a likely unintended crash in the case the system ran out of memory.
Since you can calculate exactly how much memory you need, you can implement your S_Session_new() to perform a single allocation of all the memory you need, and set the pointers to the right places within that memory. Doing so allows you to release that memory with a single call to free().
S_Session* S_Session_new() {
char *mem;
S_Session* s = 0;
size_t sz = 0;
sz += sizeof(S_Session);
sz += sizeof(AStruct);
sz += 8196;
sz += 100;
mem = malloc(sz);
if (mem) {
s = (void *)mem;
s->Id = 1;
s->buff = (void *)(mem += sizeof(S_Session));
s->buff->buffer = (void *)(mem += sizeof(AStruct));
s->buff->size = 8196;
s->name = (void *)(mem += 8196);
}
return s;
}

Related

freeing a structure array allocated with double pointer

Here is basically what I'm trying to do:
free memory that was allocated in a different scope using double pointers.
The following code is incomplete but fully describes what I'm trying to perform.
so here is my function to read the buffer (C pseudo code)
char *read_buffer(char *buf, myStruct **arr, int nbElm)
{
buf = malloc(...);
...//many things done (use of the read(),close()... functions
...//but not referencing any of the buffer to my structure
...
*arr = (myStruct *) = malloc(sizeof(myStruct) * nbElm);
return (buf);
}
Here is the kind of function I use between my memory allocation and my freeing attempt:
void using_struct(myStruct *ar, int nbElm)
{
int i;
i = 0;
while (i < nbElm)
{
// Here I use my struct with no problems
// I can even retrieve its datas in the main scope
// not memory is allocated to it.
}
}
my main function :
int main(void)
{
char *buf;
myStruct *arStruct;
int nbElm = 4;
buf = read_buffer(buf, &arStruct, nbElm);
using_struct(arStruct, nbElm);
free(buf);
buf = NULL;
free(arStruct);
while(1)
{;}
return (1);
}
The only problem is either I place my while loop before or after my free function, I can't see any memory change using top
on my terminal.
Is this normal?
Thanks in advance,
You always must have exactly same number of calls to free as a calls to malloc.
myStruct **arr;
*arr = malloc(sizeof(myStruct) * nbElm);
This means you need single call to free first nbElm structs:
free(arr);

C cleaning up on error/termination

I run a bunch of mallocs in sequence, and check each time to make sure it was successful. Something like this:
typedef struct {
int *aray;
char *string;
} mystruct;
mystruct *mystruct_init(int length)
{
mystruct *foo = malloc(sizeof(int *));
if (!foo) exit(1);
foo->array = malloc(length * sizeof(int));
if (!foo->array) exit(1);
foo->string = malloc(length * sizeof(char));
if (!foo->string) exit(1);
return foo;
}
So when a malloc fails, the program exits without freeing the previous ones. What are some techniques to make sure that in case something fails, the program exits safely with all the allocated memory freed?
Most modern operating systems would free the right memory after the process terminates after calling exit(...). These operating systems include:
all Unix variants, including Linux and Mac OS X
all Windows versions
all DOS variants
If you're designing a driver that runs as part of the OS, you'll need to take care of this more carefully. In this case, goto is often used. For example
mystruct *mystruct_init(int length)
{
mystruct *foo = malloc(sizeof(int *));
if (!foo) goto FOO_FAIL;
foo->array = malloc(length * sizeof(int));
if (!foo->array) goto ARRAY_FAIL;
foo->string = malloc(length * sizeof(char));
if (!foo->string) goto STRING_FAIL;
return foo;
STRING_FAIL:
free(foo->array);
ARRAY_FAIL:
free(foo);
FOO_FAIL:
REPORT_ERROR; // user defined behavior
return NULL;
}
So if, say, foo->string is not allocated successfully, foo->array and foo will be freed accordingly. If foo->array fails, only foo will be freed. When any of these fails, the function returns NULL, which allows the caller to check the return value and decide next step.
Here's one of my favorite tricks:
do {
a = malloc(...);
if (!a) break;
b = malloc(...);
if (!b) {
free(a);
break;
}
} while (0);
if (!a) {
...
return;
}
...
free(b);
free(a);
if you want to do post-mortem cleanup then you can register an atexit handler
http://man7.org/linux/man-pages/man3/atexit.3.html
BTW I am not saying its easy to do (or correct)
You can do it this way too, I think it's the cleanest way to do it and I use it very often, but to return from a function, not to exit from the program since it is true that system will free memory at exit.
By the way your program as is will give segmentation fault, since you are not allocating enough space for foo.
typedef struct {
int *aray;
char *string;
} mystruct;
mystruct *mystruct_init(int length)
{
mystruct *foo = malloc(sizeof(mystruct)); // you need to allocate space for string too
if (!foo)
return NULL;
memset(foo, 0, sizeof(mystruct)); // initialize all members to NULL
foo->array = malloc(length * sizeof(int));
if (!foo->array)
goto abort;
foo->string = malloc(length * sizeof(char));
if (!foo->string)
goto abort;
return foo;
abort:
if (foo->array)
free(foo->array);
if (foo->string)
free(foo->string);
return NULL;
}
now in the calling function you can do it cleanly like
mystruct *foo;
foo = mystruct_init(length /* assuming this is declared and set. */);
if (!foo)
exit(1);

How to track malloc and free? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Simple C implementation to track memory malloc/free?
I need to know how much memory I have used till now in a C program and here is the pseudo code
#include <stdio.h>
int usedMemory =0;
void *MyMalloc(int size){
usedMemory = usedMemory +size ;
return malloc(size);
}
void MyFree(void *pointer){
/*****************what should i write here????*************/
}
int main(int argc, char *argv[])
{
char *temp1= (char *)MyMalloc(100);
char *temp2= (char *)MyMalloc(100);
/*......other operations.........*/
MyFree(temp1);
MyFree(temp2);
return 0;
}
Can anyone tell me what to write in the MyFree method(which decrements the amount of memory freed from usedMemory.
You could allocate few extra bytes more than asked, and store the size in the extra bytes, so that you could know the size later on, in MyFree function, with little calculation as:
unsigned long int usedMemory = 0;
void *MyMalloc(int size)
{
char *buffer = (char *) malloc(size + sizeof(int)); //allocate sizeof(int) extra bytes
if ( buffer == NULL)
return NULL; // no memory!
usedMemory += size ;
int *sizeBox = (int*)buffer;
*sizeBox = size; //store the size in first sizeof(int) bytes!
return buffer + sizeof(int); //return buffer after sizeof(int) bytes!
}
void MyFree(void *pointer)
{
if (pointer == NULL)
return; //no free
char *buffer = (char*)pointer - sizeof(int); //get the start of the buffer
int *sizeBox = (int*)buffer;
usedMemory -= *sizeBox;
free(buffer);
}
In C++, you could keep a global std::map<void*, std::size_t> around to track the size of each allocated block; your own allocator function would register the size when allocating, and the deallocation function would remove the entry. (Update: Or do as the linked question suggests and allocate a bit more memory and save the size there.)
The more fundamental problem is that this will probably only be of very limited use in a typical C++ program: Allocations there are done predominantly in two ways: 1) through explicit new expressions, which call ::operator new(), which in turn (usually) calls malloc(), and 2) through std::allocator<T>::allocate(), which on many platforms is implemented in terms of ::operator new().
The problem is that you don't have control over the specifics of your platform. You can replace the global operator-new to use your own MyMalloc(), but the default std::allocator might use malloc() directly and thus not be affected by that.
A cleaner approach for debugging purposes is to use an external tool like valgrind to track heap usage. For permanent internal use, tracking the allocation sizes is going to cause a significant performance hit, too.
You could allocate memory and store its size in the allocated block (error checking omitted for brevity):
unsigned int totalAlloc = 0;
void *MyAlloc(unsigned int size)
{
void *p;
totalAlloc += size;
p = malloc(size + sizeof(int));
*(int *) p = size;
return (void *)(((int *) p) + 1)
}
void MyFree(void *ptr)
{
ptr = (void *)(((int *) ptr) -1 );
totalAlloc -= * (int *) ptr;
free(ptr);
}
This code actually reserves more memory than requested in order to store the block's size in the (usually) first four bytes. This information can then be retrieved later on when you free the memory.
You need to manage a list of all malloc() you have done with pointer + size. Then you can search for the size in that list, and decrement it in free().
Check for example in that example how they are doing:
http://developers.sun.com/solaris/articles/lib_interposers_code.html#malloc_interposer.c
You might have other possibilities to track memory, like:
Valgrind with massif tool for tracking memory usage over time. You can even generate png output graphics
Interposed libraries. You can found some libraries that you can use by LD_PRELOAD=thelib.so ./yourprogram, and they will output some statistics like jemalloc
(A side note, please accept some answers to your question !)
you could try something like this... i'd strongly recommend to use this only for debugging purpose!
#define MAXMEMBLOCKS 10000
typedef struct {
int size;
void* ptr;
} memblock;
typedef struct {
int totalSize;
int current;
memblock memblocks[MAXMEMBLOCKS];
} currentMemory;
currentMemory mem;
void *MyMalloc(int size) {
if (mem.current < MAXMEMBLOCKS) {
mem.current += size;
mem.memblocks[mem.current].size = size;
mem.memblocks[mem.current].ptr = malloc(size);
return mem.memblocks[mem.current++].ptr;
} else {
// you needed more memblocks than estimated
return NULL;
}
};
int MyFree(void *pointer) {
int i;
for (i = 0; i < mem.current; i++) {
if (mem.memblocks[i].ptr == pointer) {
mem.totalSize -= mem.memblocks[i].size;
free(mem.memblocks[i].ptr);
mem.current--;
return 0;
}
}
// you tried to free a block wich hasn't been allocated through MyMalloc()
return -1;
}

how free() works?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
int * ptr;
printf("before malloc pointer is :%p \n",ptr);
printf("before malloc valu is :%d \n",*ptr);
ptr = malloc(sizeof(int));
printf("after malloc pointer is %p \n",ptr);
printf("after malloc valu is :%d \n",*ptr);
int jig=32;
*ptr = jig;
printf("after assignment valu is : %d\n",*ptr);
free(ptr);
printf("after free %p \n",ptr); // after free pointer holds sane address then
printf("after fee is %d\n",*ptr); // why it coudnt print that???
return 0;
}
output is :
before malloc pointer is :0x6edff4
before malloc valu is :7265660
after malloc pointer is 0x9a52008
after malloc valu is :0
after assignment valu is : 32
after free 0x9a52008
after fee is 0
after free still pointer holds the address of that memory then why we can not print that memory's value.??
what does free() do.?
does it just make all memory as 0 ..??
after free still pointer holds the address of that memory then why we can not print that memory's value.??
Because the memory no longer belongs to you. You freed it, which means the OS is allowed to reuse it however it sees fit, wherever it needs to allocate more memory. You no longer own it, therefore you no longer have any business looking at the value of the data held by that memory.
Note also that:
int *ptr;
...
printf("Before malloc valu is :%d\n", *ptr);
is equally invalid. ptr holds a garbage value, and can point anywhere. Dereferencing it is not guaranteed to be a memory location you can access.
Both of these cases invoke undefined behavior, which means the standard says, "DON'T DO THIS," and if you ignore the standard your code will break in horrible ways whenever your boss is looking.
what does free() do.?
does it just make all memory as 0 ..??
No, not necessarily. The OS often zeroes out unused memory in the background to make calls to calloc faster, but free only tells the operating system "I'm done with this memory, do whatever you need to with it." The OS typically updates some housekeeping data to indicate that the block of memory is no longer owned by a process, so that a later call to malloc can use it if it's needed.
The interesting thing about malloc() and free() is that they don't actually change the memory they give you -- they just change how it's "thought of".
When you call malloc(), a segment of memory is chosen and dedicated to be yours. While it's yours you can use it how you like.
When you're done with it you free() it -- but it's still there. It's still the same memory[1], it's just not considered "yours" anymore. So someone else might be using it.
[1] I supposed with virtual addressing this might not be always true. But it's usually true.
free returns the memory to the system. It is the partner operation to malloc. Everything block of memory that you allocate with malloc should be returned to the system by calling free. After you call free you are no longer allowed to access that memory.
It's generally considered wise to set the pointer to NULL after you have called free, at least in debug builds, so that you can be sure that an error will be raised if you later attempt to dereference the pointer by mistake.
So, why can you still access memory that has been freed? Well, you can't reliably do so. It just so happens that the implementation of most memory management systems mean that you can sometimes get away with such abuses. Many memory managers allocate large blocks of memory from the operating systems and then, in turn, allocate small sub-blocks to the application. When you call free, the allocator returns that block back to its pool of readily available memory, but does not necessarily give the memory back to the OS, since OS memory allocation routines are typically expensive. Hence accessing it may still appear to work, because the memory is still allocated in your process. It's just that its now owned by the memory manager rather than by your app. Something like that is happening to you here.
Of course, sometimes you won't get away with abuses like this, most likely once you have deployed your software onto your most important client's machine!
Typically the memory manager will have something like a linked list of free blocks that are used to satisfy subsequent allocations.
Here's a minimal implementation I wrote several years ago. It's not really intended (or suitable) for serious use, but gives at least some general notion of one way to manage a heap:
#include <stddef.h>
typedef struct node {
size_t size;
struct node *next;
} node;
node *free_list;
static void *split_end(node *block, size_t new_size) {
size_t difference = block->size - new_size;
node *temp = (node *)((char *)block + difference);
temp->size = new_size;
block->size = difference;
return (void *)((size_t *)temp+1);
}
static void *split_begin(node *block, size_t new_size) {
size_t difference = block->size-new_size;
node *temp = (node *)((char *)block + new_size);
temp->size = difference;
temp->next = free_list;
free_list = temp;
return block;
}
void b_init(void *block, size_t block_size) {
((node *)block)->size = block_size - sizeof(node);
((node *)block)->next = NULL;
free_list = block;
}
void b_free(void *block) {
node *b = (node *)((size_t *)block -1);
b->next = free_list;
free_list = b;
}
void *b_malloc(size_t size) {
node *temp, **ptr;
size_t larger = size+sizeof(node);
size += sizeof(size_t);
for ( ptr = &free_list;
NULL != ptr;
ptr = &((*ptr)->next))
{
if ((*ptr)->size >= size) {
if ( (*ptr)->size <= larger) {
temp = (*ptr);
(*ptr) = (*ptr)->next;
return (void *)((size_t *)temp + 1);
}
else
return split_end(*ptr, size);
}
}
return NULL;
}
void *b_realloc(void *block, size_t new_size) {
node *b = (node *)((char *)block - sizeof(size_t));
char *temp;
size_t i, size;
if ( new_size == 0) {
b_free(block);
return NULL;
}
new_size += sizeof(size_t);
size = b->size;
if ( new_size <size)
size = new_size;
size -= sizeof(size_t);
if ( b->size >= new_size+sizeof(node *) )
return split_begin(b, new_size);
if ( b->size >= new_size)
return b;
temp = b_malloc(new_size);
if ( NULL == temp)
return NULL;
for ( i=0; i<size;i++)
temp[i] = ((char *)block)[i];
b_free(block);
return temp;
}
#ifdef TEST
#define num 10
int main(void) {
int i;
char block[4096];
char *temp[num];
char *big;
b_init(block, sizeof(block));
big = b_malloc(100);
for (i=0; i<num; i++)
temp[i] = b_malloc(10);
for (i=0; i<num; i++)
b_free(temp[i]);
b_realloc(big, 200);
b_realloc(big, 10);
b_realloc(big, 0);
return 0;
}
#endif

Returning a character array from a function in c

Can I return an array that is created dynamically (using malloc) inside a function back to its caller?
I know that returning a statically allocated array is wrong because the stack unwinds as the function returns and variable is no longer valid but what about a dynamically allocated variable?
Returning anything allocated with malloc is fine, as long as whoever uses your function takes care of free()ing it when they're done. malloc allocates on the heap which is essentially global within your program.
As others have noted, you can in fact return a char pointer.
However, another common method is for the caller to pass in the pointer for the method to fill along with a length parameter. This makes it so the function responsible for allocating the memory will also be the same function responsible for freeing the memory, which can make memory leaks easier to see. This is what functions such as snprintf and strncpy do.
/* Performs a reverse strcpy. Returns number of bytes written if dst is
* large enough, or the negative number of bytes that would have been
* written if dst is too small too hold the copy. */
int rev_strcpy(char *dst, const char *src, unsigned int dst_len) {
unsigned int src_len = strlen(src); /* assumes src is in fact NULL-terminated */
int i,j;
if (src_len+1 > dst_len) {
return -(src_len+1); /* +1 for terminating NULL */
}
i = 0;
j = src_len-1;
while (i < src_len) {
dst[i] = src[j];
++i;
++j;
}
dst[src_len] = '\0';
return src_len;
}
void random_function() {
unsigned int buf_len;
char *buf;
int len;
const char *str = "abcdefg";
buf_len = 4;
buf = malloc(buf_len * sizeof(char));
if (!buf) {
/* fail hard, log, whatever you want */
return;
}
/* ...whatever randomness this function needs to do */
len = rev_strcpy(buf, str, buf_len);
if (len < 0) {
/* realloc buf to be large enough and try again */
free(buf);
buf_len = -len;
buf = malloc(buf_len * sizeof(buf));
if (!buf) {
/* fail hard, log, whatever you want */
return;
}
len = rev_strcpy(buf, str, sizeof(buf));
}
/* ... the rest of the randomness this function needs to do */
/* random_function has allocated the memory, random_function frees the memory */
free(buf);
}
This can lead to some overhead though if you don't know how big a buffer you'll need and need to call the function twice, but often the caller has a good idea to how large the buffer needs to be. Also it requires a little more logic to ensure the function doesn't overrun the given buffer. But it keeps the responsibility of freeing the memory with whatever is allocating the memory, while also allowing the option to pass local stack memory.
Example just returning the char*:
/* Performs a reverse strcpy. Returns char buffer holding reverse copy of
* src, or NULL if memory could not be allocated. Caller is responsible
* to free memory. */
char* rev_strcpy(const char *src) {
unsigned int src_len = strlen(src); /* assumes src is in fact NULL-terminated */
char *dst;
int i,j;
dst = malloc((src_len+1) * sizeof(char));
if (!dst) {
return NULL;
}
i = 0;
j = src_len-1;
while (i < src_len) {
dst[i] = src[j];
++i;
++j;
}
dst[src_len] = '\0';
return dst;
}
void random_function() {
char *buf;
const char *str = "abcdefg";
/* ...whatever randomness this function needs to do */
buf = rev_strcpy(str);
if (!buf) {
/* fail hard, log, whatever you want */
return;
}
/* ... the rest of the randomness this function needs to do */
/* random_function frees the memory that was allocated by rev_strcpy */
free(buf);
}
Yes you can. Just malloc() the array inside your function and return the pointer.
BUT, the caller needs to understand it needs to be freed at some point, or you'll have a memory leak.
You can certainly return an array allocated with malloc, but you have to make sure the caller of the function eventually releases the array with free; if you don't free a malloc'd array, the memory remains "in use" until program exit.

Resources