For a RF project I need to split payload for a max predefined chunk size.
For that I created a RFmsg
struct.
The unexplained part I need help in is why when I create a local instance of RFmsg
, its contents are remain in tact after function is recalled? is it a struct "thing"? or something else I'm missing ?
To solve that I know that wiping struct content after initiating will solve that, but I'm want to be sure.
for that I share a minimal code that:
void newMSG(char *msg)
simulates the splitting part of a longmsg
input.void printStrcut_content(RFmsg &_payload)
prints struct's content.- output show that only after boot, its content are gibberish, but after that, it shows the content of last struct update.
CODE:
#include <Arduino.h>
#define MSG_LEN 10
#define DEVNAME_LEN 8
char *devName = "TEST";
struct RFmsg
{
int msg_num;
int tot_msgs;
int tot_len;
char payload[MSG_LEN];
char dev_name[DEVNAME_LEN];
};
void newMSG(char *msg)
{
RFmsg _payload;
printStrcut_content(_payload);
_payload.tot_len = strlen(msg);
strcpy(_payload.dev_name, devName);
_payload.tot_msgs = (int)(_payload.tot_len / MSG_LEN);
if (_payload.tot_len % MSG_LEN > 0)
{
_payload.tot_msgs++;
}
for (uint8_t i = 0; i < _payload.tot_msgs; i++)
{
strcpy(_payload.payload, "");
for (uint8_t n = 0; n < MSG_LEN; n++)
{
_payload.payload[n] = (char)msg[n + i * MSG_LEN];
}
_payload.payload[MSG_LEN] = '0円';
Serial.print("chunk #");
Serial.print(i);
Serial.print(": ");
Serial.println(_payload.payload);
}
}
void printStrcut_content(RFmsg &_payload)
{
Serial.print("LEN: ");
Serial.println(_payload.tot_len);
Serial.print("PAyLOAD: ");
Serial.println(_payload.payload);
Serial.print("name: ");
Serial.println(_payload.dev_name);
Serial.print("tot_msgs: ");
Serial.println(_payload.tot_msgs);
}
void setup()
{
Serial.begin(115200);
while (!Serial)
;
Serial.println("\nStart");
}
void loop()
{
newMSG("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ");
delay(5000);
}
OUTPUT:
Start
LEN: 36
PAyLOAD: UVWXYZ
name:
tot_msgs: 4
chunk #0: 1234567890
chunk #1: ABCDEFGHIJ
chunk #2: KLMNOPQRST
chunk #3: UVWXYZ
LEN: 36
PAyLOAD: UVWXYZ
name:
tot_msgs: 4
chunk #0: 1234567890
chunk #1: ABCDEFGHIJ
chunk #2: KLMNOPQRST
chunk #3: UVWXYZ
LEN: 36
PAyLOAD: UVWXYZ
name:
tot_msgs: 4
chunk #0: 1234567890
chunk #1: ABCDEFGHIJ
chunk #2: KLMNOPQRST
chunk #3: UVWXYZ
-
1I also would guess that the struct just always lands on the same memory space, thus retaining the value. Though you cannot count on that. You don't have any control over that.chrisl– chrisl2022年04月05日 06:53:43 +00:00Commented Apr 5, 2022 at 6:53
-
@Juraj since it is a tiny part of much larger code, I was shocked to see this behavior repeats, at it was intentionally kept some how. what do you recommend ?guyd– guyd2022年04月05日 06:54:37 +00:00Commented Apr 5, 2022 at 6:54
-
1Just initialize the struct variable with known values at the start of your function. You just did see that behavior because you didn't do that. You should always initialize variables in functions. Only global variables get initialized implicitly.chrisl– chrisl2022年04月05日 07:33:55 +00:00Commented Apr 5, 2022 at 7:33
1 Answer 1
As described in the comments: Your local struct variable probably always is placed in the same space in memory and this part of the memory isn't overwritten by your program. When declaring local variables they are not implicitly initialized (written with a value). If you don't initialize the variable yourself, its value will be whatever data is currently in that memory space.
The compiler optimizes your code and also decides on where to place variables on the stack. In this case it is always placed at the same memory space, but you cannot count on that. It is undefined behavior and any change to your program can also change that fact. And you don't have any control over that.
This is the reason, why you should always initialize local variables before reading them.
what do you recommend ?
Just initialize the members of that struct variable before using them. Set all members to a value. You can even do that in one step together with declaring it:
RFmsg _payload = {1, 2, 3, "payload", "devname"};
-
1Just to clarify, undefined behaviour does not necessarily mean there will be zeroes there or any specific thing at all. And under certain circumstances what is there might be the same thing that was there the previous time the function was called. If you decide to not bother initialising variables because "it seemed to work last time" you will eventually find that a change to your code will come back to bite you.2022年04月11日 10:21:39 +00:00Commented Apr 11, 2022 at 10:21