We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi, I am using calloc in a function to allocate memory to my array. This function writes to the array different number of elements each time the function is called. Here is my problem. Say for the first time function writes to all the 3 locations and next time it writes to only first 2 locations. After the second call, the 3rd memory locations still contains the value written by the first function call. I understand that is the way it works.But I want to know if there is a way to erase all the locations before calling the function again? Is there any built-in function available? Also when I print the values of array initially it doesn't print zeroes. I have read that calloc initializes the memory fields to 0's. Following is the function code.
function write_to_array(int value) { int xdata *ascii_value,i; ascii_value = calloc(3, sizeof (int)); for(i=0;value!=0;i++) { mod = value%10; c = mod+'0'; ascii_value[i] = toascii(c); value/=10; } }
Have you called init_mempool somewhere in your code before the call to calloc?
If you use calloc like that in a function, you will run out of memory sooner or later... Add a free() to the mix.
If you use calloc like that in a function, you will run out of memory sooner or later... even better: If you use calloc in a '51, you will run out of memory sooner or later... and IMMEDIATELY get in trouble. once more the '51 ain't no PC Erik
You should become an evangelist Eric ;-)
I am using free() at the end of the function code. Somehow I missed to copy that line of code. And I am also manually setting the locations to '0' to make my code work for now. I was just willing to know if there is another way of doing it. But the whole point here is my 'calloc' code line not working fine. As quoted by one of you, I have not used init_mempool(). I will try including this command. Thank you Ramya
Hi all, I have just included init_mempool() in my function and it worked fine. Thanks for all your valuable replies. Ramya
You're welcome. It's probably a common mistake because the C library reference manual entry for malloc and calloc do not mention the need to call init_mempool. As others have said though, calloc really isn't suited here. Why not a simple array
int ascii_value[3] = {0,0,0};
The reason I preferred calloc is that, for now am using 3 locations but as my project extends I might end up using more locations. Thank you Ramya
for now am using 3 locations but as my project extends I might end up using more locations what on earth does that have to do with (ab)using calloc? Erik
Hi Eric, Sorry it took so long to reply. At first I was using an array. But then realized that the number of elemetns of the array are not constant each time the function is called. So I wanted some way to create a dynamic array. Using calloc and realloc I thought I could satisfy my need. The maximum array size known , I can first use calloc to allocate maximum number of memory fields. Then depending on array length I can use realloc. This is the idea I have. Guide me if I am not making proper use of calloc Thank you Ramya
The maximum array size known , I can first use calloc to allocate maximum number of memory fields. Then depending on array length I can use realloc. This is the idea I have. see below Guide me if I am not making proper use of calloc in the '51 there is NO SUCH THONG as "proper use of calloc" your array: U8 a; ... U8 z; just change it to U8 used_length; U8 a; ... U8 z; Erik
I am sorry I do not understand your sample code. Can you make it clear?
Ramya,
From your initial post, I can understand that you are writing a function which reads a number in decimal form and stores it in the ASCII form in the XRAM.
I can't understand why are you trying to use calloc and all. Any way your array index does not exceed 5 because the input parameter for the function is 'int'. Then why can you constantly allocate some array with size 5 and clear them by just assigning it to 0?
If you call the calloc to allocate a sum of 5 bytes, I think this is not necessory.Why do you want to let the controller to go through such linked list and all? This will increase your code size and decrease your execution speed. Think over it.
But then realized that the number of elemetns of the array are not constant each time the function is called. So I wanted some way to create a dynamic array.
Bad reasoning. Just because the array size isn't the same each time a function is used doesn't justify dynamic data structures. Certainly not in an 8051-based system, and generally not in any system without swap space.
Using calloc and realloc I thought I could satisfy my need.
You could satisfy that need much more easily by just using an array of the maximal size you're actually going to need.
Rule-of-thumb: functions like malloc() and calloc() may have some sense in an small embedded system (i.e. if you have different boards with different amounts of memory, but the same software) --- but realloc() and free() are too dangerous to be allowable.
Generally, an embedded system has to guarantee performance for a certain number of elements. Thus, you have to have memory available for the worst-case table size. Given that you have a guarantee, there's little reason to dynamically allocate that memory from a heap.
Dynamic allocation is only useful when two or more functions share the same resource, and the sum of the max consumption of each function exceeds the total resources available. If you just malloc() and free() and expect the arbitration to happen at run time, then you run the risk of being unable to operate at run time. Many embedded systems, unlike desktop apps, can't tolerate this sort of sudden and unpredictable failure, even if it's rare.
It's often useful to partition system resources between two functions depending on the application. Perhaps your system can support up to 32 widgets, or up to 16 gadgets, or any combination where a gadget takes twice the memory of a widget, say 16 widgets and 8 gadgets. You might use malloc() to chop up this heap into two pieces once at configuration time. This system would never call free() until it was reconfigured. So, the system is adjustable without recompiling, but still can guarantee performance of its configuration.
I also find it very common to dynamically allocate individual items from a particular pool -- say, message buffers. This is not a general malloc() function, though; there are many individual pools for particular purposes. Most often, the maximum size of such a pool is statically allocated, and items are of fixed size (meaning much less tracking overhead and time). But the usage of these pools is limited to a particular function of the code. There's no possibility that using a lot of items from one pool affects another. malloc() shares exactly one pool of memory between multiple functions, which is where the problems begin to creep in.
As far as linked lists and such are concerned, the 8051 has a pretty small address space. And, the architecture is poorly suited to handling pointers. Often, you'll be better off using a 8-bit or even 16-bit index into a table as the pointer in your lists, rather than an actual C pointer, which is to say memory address. It will often consume less storage, and also produce smaller and faster code than a textbook "struct MyStruct* next" implementation.
A mark/release concept is more appropriate for small embedded systems than 'alloc/free. Mr. Payson has an overview here (my apologies in advance regarding the link as this forum is having some difficulties with URLs lately):
www.htsoft.com/.../23148