473,378 Members | 1,138 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

Dynamic memory location in C

This is about how to use {malloc,calloc,alloc} in efficient way.
Also tell me about 'free' function and its use.
Sep 21 '08 #1
10 2729
Laharl
849 Expert 512MB
Have you tried Google?
Sep 21 '08 #2
gpraghuram
1,275 Expert 1GB
My suggestion would be get K&R C book and start reading it.


Raghu
Sep 22 '08 #3
Alien
61
Please do some research (or Googling) on them, try them out. If you get stuck then come here.

Don't take it the wrong way, but you can't just throw a random question like "Please explain what malloc does" without any sign of doing research on it.

malloc is one of the difficult functions i came across when I did it and if you can't be bothered doing some research on it, chances are you won't go too far in coding with it.
Sep 22 '08 #4
Tassos Souris
152 100+
The C Standard Library has 4 Memory Management Functions, and these are:
Expand|Select|Wrap|Line Numbers
  1. void *calloc( size_t nmemb, size_t size );
  2. void free( void *ptr );
  3. void *malloc( size_t size );
  4. void *realloc( void *ptr, size_t size );
  5.  
You can use the calloc , malloc and realloc functions to dynamically allocate space for objects and then use the free or realloc functions to get rid of that space when you no longer need it.
You should allocate only what storage you need and to free it as soon as you're done with it; sure it is deallocated at program termination but freeing the space you allocate when you do not need it, provides you more resources and prevents memory leaks which is a common problem.
The functions work together; mallloc , calloc and realloc return a pointer to the allocated space (if successful) and free and realloc may accept that pointer to deallocate the space it points to; that is made available for further allocation.

Let's say that you have a Student object defined as:
Expand|Select|Wrap|Line Numbers
  1. struct Student{
  2.      char *name;
  3.      char *surname;
  4.      /* add more here... */
  5. };
  6.  
To allocate space for a struct Student object you can use this code:
Expand|Select|Wrap|Line Numbers
  1. struct Student *student = NULL; /*notice the initialization to NULL here! */
  2.  
  3. student = ( struct Student * )calloc( 1, sizeof( struct Student ) );
  4.  
  5. if ( student == NULL ){
  6.    /* handle memory failure here */
  7. }
  8.  
  9. student->name = NULL;
  10. student->surname = NULL;
  11.  
  12.  
Notice something:
calloc allocates space for an array of nmemb objects each of whose size is specified by size and initializes the space to all bits zero.
malloc allocates space for an object whose size is specified by size and whose value is indeterminate.
For the example i gave, i could have used this code for the allocation:
Expand|Select|Wrap|Line Numbers
  1. student = ( struct Student * )malloc( sizeof( struct Student ) );
  2.  
Which is equivalent, because i allocate space only for one struct Student object. I used the calloc function to show you something interesting.
Before moving on to the struct Student example, let me tell you this:
If you want to allocate space for an array of 3 integers then you will write:
Expand|Select|Wrap|Line Numbers
  1. arrayOfIntegers = ( int * )calloc( 3, sizeof( int ) );
  2.  
But not:
Expand|Select|Wrap|Line Numbers
  1. arrayOfIntegers = ( int * )calloc( 1, 3 * sizeof( int ) );
  2. /* or.. */
  3. arrayOfIntegers = ( int * )malloc( 3 *sizeof( int ) );
  4.  
This is not wrong but it might cause some problems when it comes to memory allignment and so on..

Let's continue with the struct Student example now:
Another thing to notice is the i typecast the return value of the calloc function to a appropriate type; you should do the same!
Then notice the if test i make; i do this to test whether i got the space i wanted for my struct Student object or not. Only if i have the space i want can i proceed processing my struct Student object.
Then comes one interesting thing. As i said above, calloc initializes all bits to zero. However, this need not be the same as the representation of a floating-point zero or a null pointer. So, for maximum portability i must not rely on name and surname attributes being null. So, i set them explicitly to NULL. Why i do that you may ask! It is very good to initialize all your variables before you use them especially the pointers (which you will set to NULL) !! As an example for this, notice that i set student to NULL before i use calloc even though i know that i will later use the calloc function.

In the beginning i said that it is very important that you have a very good memory management in your program; that is allocate space for what you want and free what you do not want at the time that you do not want it.
Let me show an example continuing the struct Student example.

Now that i have my struct Student object i want to set values to it.
Particularly, i have already read a name and a surname from the user and i want to store them as attributes to the struct Student object. Let's say that the name and surnames i already read are:
Expand|Select|Wrap|Line Numbers
  1. char *_name = NULL;
  2. char *_surname = NULL;
  3.  
  4. _name = readName(); /* assume there is a readName() function */
  5. _surname = readSurname(); /* assume there is a readSurname() function */
  6. /* Notice that these functions will call either malloc or calloc to return a pointer */
  7.  
To store them as attributes to the struct Student object you can write:
Expand|Select|Wrap|Line Numbers
  1. student->name = _name;
  2. student->surname = _surname;
  3.  
Now, the name and surname attributes of the struct Student object will point to the strings pointed to by _name and _surname respectively. However there is one problem here.. Probably, the code for the allocation of the struct Student object would be distinct from the code reading the _surname and _name. The function responsible for the allocation would accept as arguments pointers to the strings that _name and _surname point at to do the initialization at the same time. In this way, however, if the function reading the _name and _surname chooses to free them, the struct Student object will have a serious problem!!
So it is better to keep things for the struct Student object to itself; the solution to this is to make copies of the _name and _surname and assign them as name and surname attributes respectively.

One way to do this is:
Expand|Select|Wrap|Line Numbers
  1. #define MAX_LEN 100
  2. /* assume that the allocations will succeed; you must check if calloc returns NULL as in the above example */
  3. student->name = ( char * )calloc( MAX_LEN, sizeof( char ) );
  4. student->surname = ( char * )calloc( MAX_LEN, sizeof( char ) );
  5.  
  6. strcpy( student->name, _name );
  7. strcpy( student->surname, _surname );
  8.  

However, the above code has several drawbacks.
-> It wastes space; what if the _name string has only 5 characters? Then, surely i wasted a lot of space!!
-> Since, the function responsible for the allocation does not know about the function responsible for the reading of _name and _surname, then it assumes a max limit of MAX_LEN. What if _name or _surname is larger? Then strcpy will surely cause problems!!

There is a simple solution to this:
Expand|Select|Wrap|Line Numbers
  1. size_t len = 0; /* length of _name or _surname */
  2.  
  3. /* Again assume that allocations will succeed.... */
  4.  
  5. /* Obtain the length of the _name */
  6. len = strlen( _name );
  7.  
  8. /* Allocate as much space as REQUIRED */
  9. student->name = ( char * )calloc( len + 1, sizeof( char ) ); /* notice that i allocate space for len + 1 to make space for the terminating null character */
  10.  
  11. /* Make the copy safely */
  12. memmove( student->name, _name, len + 1 ); /* copy len + 1 to ensure that the terminating null character is copied; just for maximum portability */
  13.  
  14. /* Do the same as above for the _surname */
  15.  
  16. len = strlen( _surname );
  17.  
  18. ....
  19.  
So, we have seen how to allocate space and also that we must be careful about memory management with a simple example of using strlen to determine exactly how much space we want. This is just an example.

Now let's see hot to free space. This is actually very simple.
When you do not longer need the struct Student object free it using free (well you can use and realloc but leave it...)
Expand|Select|Wrap|Line Numbers
  1. free( ( void * )student );
  2. student = NULL;
  3.  
Notice that i assign NULL to student to be completely safe! I advice you to make this a rule!

But, this code is wrong!!! Not actually wrong, but in a correct memory management aspect yes it is wrong. See this new code and see why:
Expand|Select|Wrap|Line Numbers
  1. free( ( void * )student->name );
  2. free( ( void * )student->surname );
  3. free( ( void * )student );
  4. student = NULL;
  5.  
Well, this is correct. Remember you must free whatever you have allocated. Do not forget anything! There are some techniques that can help you with that... read Code Complete 2 for some examples. Notice that freeing ->name and ->surname must be done before freeing student cause after freeing student the space will no longer be accessible.

The above is just an example, actually it is very little of how tricky memory management is. I do not describe the realloc function because i do not thnk it will be of any use for you now; you need to work on malloc free and calloc .

Hope i helped!

With respect,

Tassos Souris
Sep 29 '08 #5
Banfa
9,065 Expert Mod 8TB
But not:
Expand|Select|Wrap|Line Numbers
  1. arrayOfIntegers = ( int * )calloc( 1, 3 * sizeof( int ) );
  2. /* or.. */
  3. arrayOfIntegers = ( int * )malloc( 3 *sizeof( int ) );
  4.  
This is not wrong but it might cause some problems when it comes to memory allignment and so on..
I do not think you are correct here, I can not think of any reason not to use memory allocation statements like this and I am absolutely sure that they will not cause memory alignment problems.
Sep 29 '08 #6
JosAH
11,448 Expert 8TB
I do not think you are correct here, I can not think of any reason not to use memory allocation statements like this and I am absolutely sure that they will not cause memory alignment problems.
Yep true; for a T* tp the following should be true:

Expand|Select|Wrap|Line Numbers
  1. T* tp= ...
  2. char* cp= (char*)tp;
  3. int n= ...;
  4.  
  5. if (((char*)(tp+n)) == (cp+n*sizeof(T))) puts("true")
  6.  
kind regards,

Jos
Sep 29 '08 #7
Tassos Souris
152 100+
I do not think you are correct here, I can not think of any reason not to use memory allocation statements like this and I am absolutely sure that they will not cause memory alignment problems.
To quote from Plauger:

Nor should you assume that the product of the two arguments is all that matters. An implementation can select a storage alignment for the allocated data object based on the size specified by the second argument.
I interpreted this as i said in my "large" post. Maybe i am wrong... but then what do we need the calloc function? It says allocate space for an array of nmemb objects (...). If this wasn't the case, malloc would be what we only need and we would use as an argument to the malloc function the multiplication of the two calloc arguments. Both functions have their uses.
Correct me if i am wrong to erase the related text from my "large" post.
Thank you.

With respect,
Tassos Souris
Sep 29 '08 #8
JosAH
11,448 Expert 8TB
I interpreted this as i said in my "large" post. Maybe i am wrong... but then what do we need the calloc function? It says allocate space for an array of nmemb objects (...). If this wasn't the case, malloc would be what we only need and we would use as an argument to the malloc function the multiplication of the two calloc arguments. Both functions have their uses.
Calloc may decide to allocate the memory somewhere else from where malloc
would've allocated it and, calloc sets every bit of the allocated memory to zero,

kind regards,

Jos
Sep 29 '08 #9
Banfa
9,065 Expert Mod 8TB
Nor should you assume that the product of the two arguments is all that matters. An implementation can select a storage alignment for the allocated data object based on the size specified by the second argument.
What this means is that

assuming some type T

calloc(2, sizeof(T));

is not equivalent to

calloc(sizeof(T), 2);

Because the calloc function uses the size of the 2nd parameter to determine the required alignment for the data block to be allocated. The first case given will be correct because the 2nd argument is sizeof(T) so calloc will return a block with alignment for an object of size sizeof(T). However the second case may not be correct because calloc will return a block with alignment for an object of size 2. However in both cases the product of the 2 parameters is the same.

The quote is making the point that it is important to put the object size in the second argument if you call calloc.

The first call to calloc will however allocate a block of memory of size 2 * sizeof(T) and aligned for an object of size sizeof(T).

You could directly allocate the full size memory block in either of these 2 other ways

calloc(1, 2*sizeof(T));
malloc(2*sizeof(T));

In these cases you get a block of memory of size 2 * sizeof(T) and aligned for an object of size 2 * sizeof(T). A block of memory aligned for an object of size 2 * sizeof(T) should be fine for a block of memory of size sizeof(T). If anything it will be more stringently aligned than is actually required.

So

calloc(2, sizeof(T));

can be replaced by

calloc(1, 2*sizeof(T));
or
malloc(2*sizeof(T));

without a problem but must not be replaced with

calloc(sizeof(T), 2);


As to your point about the pointlessness of calloc you are right their is not much point to that function. I have seen several implementations where calloc just calls malloc and then memset and most of the projects I have worked on that used heap memory tended to use malloc exclusively.
Sep 29 '08 #10
Tassos Souris
152 100+
OK, thank's for that information!!
Sep 29 '08 #11

Sign in to post your reply or Sign up for a free account.

Similar topics

3
by: meyousikmann | last post by:
The following code just sets up and fills a dynamic array of integers. #include <cstdlib> int main() { int* intArray = NULL; int count; count = 20;
8
by: Peter B. Steiger | last post by:
The latest project in my ongoing quest to evolve my brain from Pascal to C is a simple word game that involves stringing together random lists of words. In the Pascal version the whole array was...
5
by: swarsa | last post by:
Hi All, I realize this is not a Palm OS development forum, however, even though my question is about a Palm C program I'm writing, I believe the topics are relevant here. This is because I...
10
by: s.subbarayan | last post by:
Dear all, I happen to come across this exciting inspiring article regarding memory leaks in this website: http://www.embedded.com/story/OEG20020222S0026 In this article the author mentions:...
15
by: Ronny Mandal | last post by:
Assume that you want to store n records in an array, and that the array can hold all n elements, that is, it is declared int a. And suddenlny in run-time, I need to store n+m items. Why cannot...
3
by: Stephen Gennard | last post by:
Hello, I having a problem dynamically invoking a static method that takes a reference to a SByte*. If I do it directly it works just fine. Anyone any ideas why? I have include a example...
9
by: Spoon | last post by:
Hello everyone, As far as I understand, if I request a uint8_t buffer, it could be allocated anywhere. uint8_t *buf = new uint8_t By anywhere, I mean e.g. it could start at an odd address....
7
by: Frank | last post by:
Hi, I have the following problem with dynamic memory: int main(){ for(){ int (**w)=new int *; for(m = 0; m < N1; m++) {
1
by: Peterwkc | last post by:
Hello all expert, i have two program which make me desperate bu after i have noticed the forum, my future is become brightness back. By the way, my problem is like this i the first program was...
4
by: Atemporal | last post by:
hi, all, i got some problem when define and use large dynamic two dimension arrays. At first, i use vector<vector<double>p1, i have three such arrays and each is around 10000*10000, the program...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.