Struct with a char[] #32
-
Do you have an example of how to build a circular buffer using a struct that has a char[] as one of the variables? Your struct example works fine until I try to add a char type variable. |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 1 reply
-
What's the error you are encountering? |
Beta Was this translation helpful? Give feedback.
-
I can only add 1 character and need the var to hold 2 or more. Here’s my attempt to use your example but simplify it, with a variable Time that holds 2 chrs plus terminator. Can you please show me how to make this work?
```cpp
/*
Test using char only
*/
#include <CircularBuffer.h>
//Define some user variables
char Time[2];
//Define a name space named 'record' and put some namespace variables inside
namespace data {
typedef struct {
char theTime[2];
} record;
//Make a function to retrieve the variables and put them into the user variables
void retrieve(record r) {
//Time = r.theTime;
memcpy(Time, r.theTime, 2);
}
}
//Define the circular buffer
CircularBuffer<data::record, 10> theBuffer;
void setup() {
Serial.begin(9600);
Serial.println("STARTING UP");
}
void loop() {
//Put the chars in the buffer
for (int i = 0; i < 2; i++) {
Time[i] = char(random(65, 122));
}
//Time[2] = '\0';
theBuffer.unshift(data::record{Time[1]});
//For each line in the buffer . . .
for (int i = 1; i <= theBuffer.size(); i += 1 ) {
//Retrieve the buffer data (starts at 0)
data::retrieve(theBuffer[i - 1]);
//Print each value
Serial.print(i);
Serial.print(" ");
Serial.println(Time);
}
Serial.println();
delay(4000);
}
```
|
Beta Was this translation helpful? Give feedback.
-
First of all, I had your very same issues when I returned to C/C++ after some years, so don't feel bad about it. Your Now, to avoid all the fuss and trying not to be an old fart as I usually am, here is the #include <CircularBuffer.h>
namespace data {
typedef struct {
char* time;
unsigned int value;
bool flag;
} record;
void print(record r) {
Serial.print(r.time[0]);
Serial.print(r.time[1]);
Serial.print(" ");
Serial.print(r.value);
Serial.print(" ");
Serial.print(r.flag);
}
}
CircularBuffer<data::record, 10> structs;
#define SAMPLE_PIN A0
void setup() {
Serial.begin(9600);
Serial.println("STARTING UP");
}
char* generate() {
char* p = malloc(sizeof (char) * 3); // memory is dinamically allocated
for (int i = 0; i < 2; i++) {
p[i] = char(random(65, 122));
}
return p;
}
void loop() {
unsigned int sample = analogRead(SAMPLE_PIN);
if (sample != structs.last().value) {
structs.push(data::record{generate(), sample, sample > 512});
Serial.print(".");
delay(50);
}
if (structs.isFull()) {
Serial.println("Stack is full:");
while (!structs.isEmpty()) {
data::record i = structs.shift();
data::print(i);
Serial.println();
free(i.time); // necessary to free up memory: fail to do this and your program will eventually crash
}
Serial.println("START AGAIN");
}
} Please note how memory allocation and deallocation of the so-called array is done |
Beta Was this translation helpful? Give feedback.
-
BTW, your problem has nothing to do with CircularBuffer, but with memory allocation and variable scoping |
Beta Was this translation helpful? Give feedback.
-
And just for completeness, this is the same but without using dynamically allocated memory: #include <CircularBuffer.h>
namespace data {
typedef struct {
char time[2];
unsigned int value;
bool flag;
} record;
void print(record r) {
Serial.print(r.time[0]);
Serial.print(r.time[1]);
Serial.print(" ");
Serial.print(r.value);
Serial.print(" ");
Serial.print(r.flag);
}
}
CircularBuffer<data::record, 10> structs;
#define SAMPLE_PIN A0
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("STARTING UP");
}
void generate(char p[], uint len) {
for (int i = 0; i < len; i++) {
p[i] = char(random(65, 122));
}
}
void loop() {
unsigned int sample = analogRead(SAMPLE_PIN);
if (sample != structs.last().value) {
data::record entry = {"", sample, sample > 512};
generate(entry.time, 2);
structs.push(entry);
Serial.print(".");
delay(50);
}
if (structs.isFull()) {
Serial.println("Stack is full:");
while (!structs.isEmpty()) {
data::record i = structs.shift();
data::print(i);
Serial.println();
}
Serial.println("START AGAIN");
delay(250);
}
} |
Beta Was this translation helpful? Give feedback.
-
Roberto:
Thank you for this! I have it working as I needed it to.
Your previous example using malloc and free threw an error on the malloc line (invalid conversion from void to char. I’m using an Arduino MKR1010 for this project. ) This got me to reading various posts about using malloc and free and warned about memory leaks and problems debugging code that use these calls. I elected to not use them as the risk would be too great and I am not experienced enough to deal with them
.
This version doesn’t seem to have those problems.
Regards,
Ben
… On May 21, 2020, at 6:42 AM, Roberto Lo Giacco ***@***.***> wrote:
And just for completeness, this is the same but without using dynamically allocated memory:
#include <CircularBuffer.h>
namespace data {
typedef struct {
char time[3];
unsigned int value;
bool flag;
} record;
void print(record r) {
Serial.print(r.time[0]);
Serial.print(r.time[1]);
Serial.print(" ");
Serial.print(r.value);
Serial.print(" ");
Serial.print(r.flag);
}
}
CircularBuffer<data::record, 10> structs;
#define SAMPLE_PIN A0
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("STARTING UP");
}
void generate(char p[]) {
for (int i = 0; i < 2; i++) {
p[i] = char(random(65, 122));
}
}
void loop() {
unsigned int sample = analogRead(SAMPLE_PIN);
if (sample != structs.last().value) {
data::record entry = {"", sample, sample > 512};
generate(entry.time);
structs.push(entry);
Serial.print(".");
delay(50);
}
if (structs.isFull()) {
Serial.println("Stack is full:");
while (!structs.isEmpty()) {
data::record i = structs.shift();
data::print(i);
Serial.println();
}
Serial.println("START AGAIN");
delay(250);
}
}
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub <https://github.com/rlogiacco/CircularBuffer/issues/32#issuecomment-632093124>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AA4VN55RZNR33OJWYCXKKBTRSUVUBANCNFSM4NEKVZZQ>.
|
Beta Was this translation helpful? Give feedback.
-
I'm happy to have helped you out. The warning you were receiving (it's not an error) it's normal and is telling you I didn't explicitly cast the pointer, but that is not an issue in this case. Even if dynamic memory allocation is not widespread in the Arduino world, it's not something you should be scared of, there's no magic, just a matter of being sure to clean the kitchen once you had your dinner or you'll end up with mice and bugs running around your valuable food ;) |
Beta Was this translation helpful? Give feedback.
And just for completeness, this is the same but without using dynamically allocated memory: