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; } }
I cant understand your problem. If the number of items in calloc call is fixed and it is only '3' then why cant you do it your self? some thing like:
ascii_value[0] = 0; ascii_value[1] = 0; ascii_value[2] = 0;
If the number of items in calloc call is fixed and it is only '3' then why cant you do it your self? Because calloc is supposed to return a memory block that is initialized with zeros. If it doesn't do that, something is wrong.
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
Thank you all for making it very clear when to go for dynamic allocation. As most of you have said, I have changed my code to use an array of max size. Thank you Ramya
"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."
Another case where dynamic allocation is useful is where the available resource is unknown at build time. This is quite rare in embedded systems, but very common indeed on PCs and the like.
Because standard 'C' textbooks tend to be written with general-purpose computer targets in mind (PCs, etc), they tend to take dynamic allocation as read
This is quite rare in embedded systems, but very common indeed on PCs and the like.
This contains another lesson about dynamic allocation:
It should only be used in cases where the program has a sensible option if the allocation fails. Your PC can bark "Not enough memory, stoopid." at you and exit the program. Your uC most likely can't.
Thank you all for making it very clear when to go for dynamic allocation
If it is 'clear' then why state it as the above, why not state
NEVER use dynamic allocation on a '51.
Since there will be exceptions to every rule, I am sure that there is one case in 1.000.000 where it is correct to use it, but I have not heard of it. That there will be one case in much less than 1.000.000 where it is used, does not make it right
There are features in Keil C51 that should not be there simply because they have to be "wresteled into the architecture" but Keil need to be able to state "ANSI compatible" so they are there.
Erik
I don't think you're in a position to comment on "ANSI compatibility" having never actually read the document in question.
If you'd like to give us all a laugh by inventing some examples to back up your statement please go ahead.
i posted "Keil need to be able to state "ANSI compatible" "
I don't think you're in a position to comment on "ANSI compatibility" having never actually read the document in question. The "document in question" is the Keil sales litterature, not the ANSI standard. And, contrary to your opinion, I have read that.
If you'd like to give us all a laugh by inventing some examples to back up your statement please go ahead. I'll gladly provide some fun, but examples of WHAT?.
However fun is one thing, derision is another and, it seems, you do not know the difference.
I'll gladly provide some fun, but examples of WHAT?.
Examples of features in Keil C51 that should not be there simply because they have to be "wresteled into the architecture" but Keil need to be able to state "ANSI compatible".
Examples of features in Keil C51 that should not be there simply because they have to be "wrestled into the architecture" absolutely: dynamic allocation function pointers most often (have yet to find a 'no'): floating point
The usage of the above in a '51 sigularily indicate the users inability to select a suitable processor for the job.
the unique structure of the 51 with 3,4,5 or 6 types of memory (depending on how you count) in combination with the Harward architecture makes it an extremely suited controller for the applications it is designed for. However any attempt to use it as a general purpose processor will, at best be clumsy, and sometimes even impossible (who wants to wait 5 minutes on an answer to "what is the log of 1.349264?")
If using floating point on a '51 makes sense, then it would equally well make sense to use a Pentium for a toy. Either would represent a bad processor choice.
Examples of features in Keil C51 that should not be there simply because they have to be "wrestled into the architecture"
As usual you've snipped the quote to change the meaning so I'll repost what you actually said:
Here's your first example of something to satisfy the above statement:
absolutely: dynamic allocation
Guess what? You're wrong. I'll leave it to you to read that nice new copy of the standard you've bought to find out why.
<usual "'51 ain't no PC" rubbish snipped>
There are features in Keil C51 that should not be there simply because they have to be "wresteled into the architecture" but Keil need to be able to state "ANSI compatible" so they are there. I have not "snipped the quote to change the meaning"
If you have a problem with english, let me try another way 1) There are features that The ANSI standard state a compliant C compiler must have. 2) To be able to state "ANSI C compatible", Keil need to include these feastures 3) Some such features are extremely combersome in the implementattion on the '51 architecture 4) Thus using such feature dramatically reduce the efficiency of the resulting code. 5) an example of such a feature would be dynamic allocation
now I have cut it in cardboard, and bent it in neon please elaborate on Guess what? You're wrong.
I'll leave it to you to read that nice new copy of the standard you've bought to find out why. I have no intention of purchasing a "nice new copy of the standard", till a problem should come up which what I have for a reference does not suffice. What I
I have no intention of purchasing a "nice new copy of the standard"
It's a pity, because if you did so (and read it, of course) you'd be able to avoid making false statements.
Dynamic allocation is not required to be implemented by a freestanding implementation.
ok 1) what is a 'freestanding implementation' ? 2) so I possibly missed one, what about function pointers which are a nightmare in the '51?
"1) what is a 'freestanding implementation' ?"
Aha - that's a term defined in the Standard...! ;-)
that's a term defined in the Standard will it cost me the price of the standard to find out or are you, Andy, going to tell me?
"will it cost me the price of the standard to find out ...?"
No. As posted elsewhere here, if you don't want to spend the small sum of $30 to buy from ANSI, you can get a working paper reflecting the current approved standard www.open-std.org/.../n1124.pdf from the working group's web page www.open-std.org/.../
i read the definition and am none the wiser.
I admit, I am limited in my C scope, since 1987? I have not written even a single line for a PC, only for 'small embedded'. For that very reason, I have had no reason to look at the C standard since then.
"i read the definition and am none the wiser."
OK then, take a look at the C Rationale:
www.open-std.org/.../C99RationaleV5.10.pdf
Section 4, lines 9-13:
"By defining conforming implementations in terms of the programs they accept, the Standard 10 leaves open the door for a broad class of extensions as part of a conforming implementation. By defining both conforming hosted and conforming freestanding implementations, the Standard recognizes the use of C to write such programs as operating systems and ROM-based applications, as well as more conventional hosted applications."
Hopefully that sets the stage for The Standard's Section 4, paragraph 6:
"The two forms of conforming implementation are hosted and freestanding. A conforming hosted implementation shall accept any strictly conforming program. A conforming freestanding implementation shall accept any strictly conforming program that does not use complex types and in which the use of the features specified in the library clause (clause 7) is confined to the contents of the standard headers <float.h>, <iso646.h>, <limits.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, and <stdint.h>. A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any strictly conforming program.)"
Hence Jack Sprat's comment about dynamic allocation not being required. Another example would be I/O as provided by the stdio.h interface (e.g., printf, putchar, etc.).
I read the very same and were none the wiser.
so, can it be expressed as "A conforming freestanding implementation excludes some standard C library funtions"
'so, can it be expressed as "A conforming freestanding implementation excludes some standard C library funtions"'
Yes, but specifically those facilities that would otherwise be provided by the list of headers not in the freestanding list: assert.h, complex.h, ctype.h, errno.h, fenv.h, inttypes.h, locale.h, math.h, setjmp.h, signal.h, stdio.h, stdlib.h, string.h, tgmath.h, time.h, wchar.h, and wctype.h.
thanks Dan
now back to the original issue
"A conforming freestanding implementation" still allow function pointers which, as i stated are "wrestled into an unsuited architecture"
'"A conforming freestanding implementation" still allow function pointers which, as i stated are "wrestled into an unsuited architecture"'
Yes, in fact must allow in order to be conforming. How an implementation achieves that conformance (i.e., code production) for a language feature and whether or not that suits the target application's requirements for functionality versus performance is left as an exercise for the developer.
since 1987? I have not written even a single line for a PC, only for 'small embedded'. For that very reason, I have had no reason to look at the C standard since then.
This is exactly the sort of attitude that has resulted in the world being full of unmaintainable, non-portable code.
The 'C' standard applies to the 'C' language, not the platform.
I posted "A conforming freestanding implementation" still allow function pointers which, as i stated are "wrestled into an unsuited architecture"
Since you can not 'attack' that statement, instead you attack my 'attitude'
'portability' is arguable, but DO NOT accuse me of unmainatainable code, you have no foundation for that. Having the C standard in one hand while typing with the other is NOT a requirement for mainatainable code, au contraire, the least maintainable code I have seen has been written by people discussing whether code is "Real C".
Portable code for a uC you have got to be kidding. That is one of those absolute fallacies that keep coming up.
I guarantee you that my code is far more maintainable than much code I have seen that was littered with 'portability switches'. I can quote a statement I have made several times: "I do not give a hoot if code works, I care if it is maintainable". You can fix maintainable code that does not work, but get a bug report on unmaintanable code that 'works' and you are in deep Doo-Doo.
Were I to replace a '51 with e.g. an ARM the code (even if written by Jack Sprat) would by no description imaginable be 'portable'. Is it possible to 'port' such code, sure, but that you just load it into the other compiler because C code is portable is pure and unadulterated BULLSHIT when talking about microcontrollers.
There is so much going on in certain quarters to make a 'port' of something that 99.23% sure is never going to be 'ported' possible - what a wasted effort.
PS looking forward to seing what you can attack in this post :)
View all questions in Keil forum