Go Down

Topic: Simple, useful additions to HardwareSerial (Read 2962 times) previous topic - next topic

sterretje

Can't free the buffer upon entry, because the FIRST time in, the buffer was never allocated and you get a "double free corrupt" error.
No, if it's a static pointer, you can test for NULL.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

-dev

Quote
Why on earth would I put 80 bytes of string data used by a DEMO program when they will fit with tons of room to spare even in a lowly ATtiny25?
You said the goal was minimal RAM, so I thought it was ironic for you to waste RAM.  If that's not the goal, why would you worry about wasting RAM on a buffer that is too big?  You said,

Quote
The alternative is to allocate a "best guess sized" buffer and hope that (A) it's big enough and (B) that it's not too big, thereby wasting ram.
But this is exactly what you do when you use sprintf!

I guess I'm having trouble following your logic.  I'm not trying to be condescending, but if you set the criteria, expect us to refer to them.

Quote
And, if I were to put the strings in flash, I would use PROGMEM
Ok, but you'll have to use the __FlashStringHelper type if you want to reuse all the methods that have been written for it.  It's present in the core and many, many libraries.  There is no other language element to distinguish between FLASH and RAM: you have to use a distinct type.

Quote
As far as "println()" is concerned, know that I DESPISE the whole idea of building a simply line of text up by using a half dozen "Serial.print......." lines (ala the sadistic programming style of Java and Javascript).
Did you read this reply?  A series of prints is not from Java nor Javascript.  The streaming operator...

    Serial << "RAM string " << f << ',' << HEX << i << endl;

...  would be considered the contemporary C++ way of printing multiple items, as opposed to the ancient printf family.  And I don't mean "ancient" in a derogatory way.  printf et al have endured because they are so useful.  But they are old routines, not the "C++ right way."

To summarize:

*  You didn't know that parseInt blocks.
*  You didn't suggest a derived class of HardwareSerial.  This is a classic example of extending a class.
*  You didn't know why malloc is bad, or that there are good and bad malloc strategies.
*  You didn't handle CR and/or LF.  This is a classic portability issue.  Classic.

There is nothing wrong with not knowing these things... we like sharing the knowledge (that's not condescension).  And we can't read your mind, so we don't know what you know (that's presumptive, not presumptuous).  But if you don't like the forum scrutiny, don't stand on the podium and suggest "simple, useful additions" to the core.

Cheers,
/dev
Really, I used to be /dev.  :(

krupski

No, if it's a static pointer, you can test for NULL.
You are not seeing the problem. The way it works, in sequence, is this:

(1) Pointer is NULL
(2) User types in some characters. Ram is allocated for each byte
(3) Upon pressing Enter, the allocated, valid pointer with user text is returned to the caller
(4) The caller uses the data
(5) The caller frees the allocated ram.

If the pointer were freed before exiting the readline (or upon entering it), the function would always return a null pointer to the caller (i.e. with no data).

Picture a small whiteboard. Imagine I am the user and you are the calling function. You ask me to write something on the board, I do it, then hand the board to you. You do whatever you want with the data, then erase the board and hand it back to me.

However, if *I* erased the board before I handed it to you, what good would it do you?  See?

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

krupski

1  You didn't know that parseInt blocks.
2  You didn't suggest a derived class of HardwareSerial.  This is a classic example of extending a class.
3  You didn't know why malloc is bad, or that there are good and bad malloc strategies.
4  You didn't handle CR and/or LF.  This is a classic portability issue.  Classic.
(1) Which "parseint" are you talking about? If there is some other function with that name and it blocks, then OK. But the one I posted does not block anything. It merely calls "strtol()" and returns the long int value of the numeric text string supplied to it. Sure it uses a few CPU cycles, but that's not "blocking".

(2) I fully intended to extend the HardwareSerial class, giving it a few more useful functions.  As it is, the HardwareSerial class in the newer 1.6.x IDE has a few added functions (i.e. it's been extended) beyond what came with the 1.0.x IDE.

(3) Disagree. You still have not told me WHY "malloc is bad", nor provided any references or links to info to back up that claim.

(4) You've got me there. I did indeed "screw up" by not properly handling the odd "CR AND LF" end of line combo.



Quote
Quote
As far as "println()" is concerned, know that I DESPISE the whole idea of building a simply line of text up by using a half dozen "Serial.print......." lines (ala the sadistic programming style of Java and Javascript).
Did you read this reply?  A series of prints is not from Java nor Javascript.

The streaming operator...
   Serial << "RAM string " << f << ',' << HEX << i << endl;
I said "programming style" of Java and Javascript.

And, maybe I can't see it, but this:

Serial << "RAM string " << f << ',' << HEX << i << endl;

looks NOTHING like this:

Serial.print ("RAM string ");
Serial.print (f);
Serial.print (",");
Serial.print (i);
Serial.print ("\n");


which looks a lot like this (Java):

String str = new String;
str += "RAM string ";
str += f;
str += ",";
str += i;
str += "\n";
System.out.print (str);


As I said, sadistic.... making programmers type all that cr...um junk.

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

-dev

Quote from: Krupski
Which "parseint" are you talking about?
This one.  This tells me that you have not investigated the base classes.

Quote
You still have not told me WHY "malloc is bad", nor provided any references or links to info to back up that claim.
Dear Sweet Fuse Bits, this deserves Presumptuousness and Condescension, because I've told you twice.  Instead, I'll suggest that you go back and read reply #14:

There is no hand-waving or mumbling here, just the facts.  Several links discuss why it's generally bad to use it, but be sure to read "The Evils of Arduino Strings" -- it is focused on our environment.
... or reply #25:

It's not just a rumour.  Read all about it here, like I mentioned earlier.  If you only read one of the links, read "The Evils of Arduino Strings".
I must be presumptive and point out that all underlined teal text (except this one) is a link, and that the evil part of the String class is its use of malloc.

Out of cheer,
  Out of patience, and
    Out of pearls,
      /dev
Really, I used to be /dev.  :(

Coding Badly

#35
Dec 21, 2016, 06:39 pm Last Edit: Dec 22, 2016, 05:58 am by Coding Badly
(1) Which "parseint" are you talking about? If there is some other function with that name and it blocks, (3) Disagree. You still have not told me WHY "malloc is bad", nor provided any references or links to info to back up that claim.
After decades of people researching dynamic memory allocation and, more recently, Google's indexing efficiency, taking the time to spoon feed you a link should not be necessary but here you go...
https://www.google.com/search?q=realloc+fragmentation


Coding Badly


@Krupski, the code you posted has a rather nasty bug.  (@sterretje copied the bug.)


Go Up