Sets up room for the book POINTER, but not any data it points to - you'd need an additional memory allocate. So when you do this later:
strncpy(book->phrase, tmp, strlen(tmp));
You're sending the data to who-knows-where.
you're repeatedly adding to a String. This code:
data += val;
Causes you to take the old copy of data, make a new copy, and splice on the entry val. So the first time, you use one byte (empty data, one char val), the next time, you lose 1 byte, and end up with 2, for a total of 1+2 bytes in use (without memory management, the old value of data is never cleaned up, wasting space). Following this progression, the next loop will take up 1+2+3, then 1+2+3+4, and so on (possibly more, depending on how string is designed). By the time you've read in about 100 characters, you'll have used up about 5050 bytes of memory! Try a char buffer instead.
you're over complicating your code. I'd recommend using a simple point for now, and then add in the book structure once you've got the code running (if at all). It's one more layer of indirection that's causing problems.
By the way, when you say that the old value of data is never cleaned I think that's not true. In fact, when you're sending any char to serial port, val receives every char until reach # char, print to console and reset the data value, as you can see below (I deleted a few lines to be much clearer). I suppose this code is right.
if (Serial.available()> 0){
val = Serial.read();
if (val != '#'){
data += val;
} else {
Serial.print("Data: ");
Serial.println(data);
data = "";
}
}
In the end, my simple purpose is save a bunch of Strings in a char* form (easily to convert later to integer, long or float)
I'm glad I could help - looking at your code, the phrase is still a problem, even though it seems to work for you - what you are doing is setting up a pointer. Try changing this
char* phrase;
to this
char phrase[100];
You'll only be able to store 100 characters, but now you've given them a place to stay (the char *phrase was only a pointer - you hadn't set where it was to go to).
As for the missing memory values, I wasn't being clear enough - the problem is that the String needs a physical location in memory to stay, and when you add a character to it, it needs to move. Unfortunately, the old place is still needed for the original string (at least until you're done adding the character), so for a while you have two copies in memory - the old and new. After you've added a character, the old copy is deleted - but its location can't be reused easily. It's called a memory hole, and I believe the Arduino String doesn't handle that in a way that saves memory.
So as you add another character, and another, and another, you create more and more holes - even though you have only one string, the holes prevent you from using the remaining space properly.
So the first time, you use one byte (empty data, one char val), the next time, you lose 1 byte, and end up with 2, for a total of 1+2 bytes in use (without memory management, the old value of data is never cleaned up, wasting space). Following this progression, the next loop will take up 1+2+3, then 1+2+3+4, and so on (possibly more, depending on how string is designed). By the time you've read in about 100 characters, you'll have used up about 5050 bytes of memory! Try a char buffer instead.
Take a look at the String class' code. The += operator function looks like:
The realloc function handles freeing the old space that was used by the String object being added to.
The String class is not very efficient, though, in that the internal space available to store data, _capacity, is never larger than the data currently being stored, so there is never excess capacity, so the original contents always need to be copied.