I am having a problem getting valid boolean data from a pointer. If
I print out the dataBit variable in the readDataBit() function I get either a 1 or a 0 (great)... but if I print it out in the calling function I get a completely different (non-boolean) number.
What am I doing wrong?
boolean * readDataBit() {
boolean dataBit = false;
//
// logic sets boolean to true or false
//
Serial.print("bit: ");
Serial.println(*dataBit, DEC); // this prints 1 or 0
Thanks for the advice. I am freeing up the memory in the code that calls the readBitData(). I am returning a pointer because i needed some way to represent NULL data (e.g. the end of a bit stream). I wanted to use a boolean type to represent a bit rather than an integer because it seemed to more closely resemble the data I was looking for represent (a bit).
Does this seem kludgy to you? I read that anytime you are given a pointer to data from a function call that you should presume it needs to be freed... so the function depends on the user-programmer to free the data... Is this good practice?
Any advice on what is considered elegant and what is not is very welcome!
Mac, your reasoning and explanation are both very sound. You really want a data type that has three states, right, "on", "off", and "null".
I think your scheme probably works fine, although I think if I were implementing it, I don't think I'd use the dynamic allocation, obviously because there is always that slight danger of introducing bugs with mismatched malloc/free pairs, but also because it introduces a bit of inefficiency, both in terms of space and time. Every call to your readDataBit consumes three bytes: the 2-byte pointer, plus the 1-byte boolean value, so that's actually less efficient than if you had chosen int or byte as the return value in the first place. Also, you suffer a performance penalty, because every call to malloc and free adds an unnecessary waste of processing time.
Bravo for conceiving and acting upon the idea that a boolean "more closely resembles the data" you are trying to represent. This is a very good programming practice. In this case, though, boolean may not quite suffice, because of the need to also represent the "end" token. I think if I were building this, I'd probably write:
enum {BIT_ON, BIT_OFF, BIT_END};
byte readDataBit()
{
...
return BIT_ON;
...
return BIT_END;
}
// usage:
byte dataBit = readDataBit();
if (dataBit == BIT_END) // do something for end of stream
If you really want to use boolean, you could write readDataBit() to return a success/failure to indicate whether the end of the bit stream had been reached and modify dataBit as a reference parameter.
While I have your ear. I also would like to return an array of bytes from the method that calls readDataBit() (as that is ultimately what i am constructing out of the bits). It seems that there is no easy way to do this in C however so I have resorted to using a home spun linked list (which seems ugly).
That's not too bad! Inside ByteArray how do you create the "data" buffer, and how do you know how big to make it? BTW, that is not a strictly speaking linked list.
One alternative that would circumvent having to do dynamic allocation would be to have the caller pass a pointer to the array and its size like this:
As I cannot tell beforehand how much data there is to read I cannot pass in a statically sized array. Sometimes the data is 40 bits long and other times it is 26 bit or much larger or smaller.
I know that the struct I pasted isn't a linked list... I decided that I wanted to use a more traditional array instead so I changed it
(Sorry I should also note that I chagned the name of the typedef from 'ByteArray' to 'byte_array_s' as it seemed more 'C'ish)
Keep in mind that if you use realloc() in that way, you are limiting your already precious RAM supply. There would be no way, for example, to increase the size of your buffer from 512 to 513 bytes, because realloc requires (for a time anyway) both the old and new buffers to be simultaneously allocated.
Do you have any notion what the maximum possible size for the array is? If it's pretty large, I would recommend the static byte array that is passed in by the caller, or possibly even a bit array.
Adding a method to a struct is not ANSI C, nor C of any kind. That is a C++ technique. But there is no problem here; Arduino is C++ (almost) all the way. (An interesting bit of trivia is that the only difference between a struct and a C++ class is the default member visibility: public for struct and private for class.)