I'm using Energia to program one of TI's MCU. Since Energia is based off the Arduino IDE, I'm hoping someone can help me here.
I'm building a simple UDP packet sender and receiver app. The MCU starts up and connects to the local Wifi network and waits for a packet from another device on the same network.
This packet is collected in a char array char packetBuffer[16];
I want to split this array into two separate arrays each of 8 elements. These are char lampCmdRead[8];
and char pwdReadBuffer[8];
Now the network bit works great. I can send the packet through my desktop and receive it on the MCU. However when I split this array I see that the pwdReadBuffer
shows the same contents as packetBuffer
even though they are of different sizes. How is this possible?
Here is the code:
char packetBuffer[16];
char lampCmdRead[8];
char pwdReadBuffer[8];
// This is code from the 'void loop()' section
int packetSize = Udp.parsePacket();
if(packetSize) {
int len = Udp.read(packetBuffer, 16);
if (len > 0) packetBuffer[len] = 0;
Serial.println();
Serial.println("packetBuffer:");
Serial.println(packetBuffer);
Serial.println();
for(ctr = 0; ctr < 8; ctr++) {
pwdReadBuffer[ctr] = packetBuffer[ctr];
}
if (len > 8) pwdReadBuffer[len] = 0;
for(ctr = 0; ctr < 8; ctr++) {
lampCmdRead[ctr] = packetBuffer[ctr+8];
}
if (len > 8) lampCmdRead[len] = 0;
Serial.println("pwdReadBuffer:");
Serial.println(pwdReadBuffer);
Serial.println();
Serial.println("lampCmdRead:");
Serial.println(lampCmdRead);
Serial.println();
}
And here is the output:
Received packet of size 16
From 192.168.1.101, port 55056
packetBuffer:
2qZ@X51Rredledon
pwdReadBuffer:
2qZ@X51Rredledon
lampCmdRead:
redledon
-
You're overflowing your buffers.Majenko– Majenko2016年06月04日 21:19:03 +00:00Commented Jun 4, 2016 at 21:19
-
Also you're not terminating your strings properly.Majenko– Majenko2016年06月04日 21:19:48 +00:00Commented Jun 4, 2016 at 21:19
2 Answers 2
if (len > 8) pwdReadBuffer[len] = 0;
This line is unsafe. You declared pwdReadBuffer to be only 8 bytes in size, but this line of code will either do nothing, or write outside of the target buffer, with unpredictable results.
You make a related mistake here:
if (len > 8) lampCmdRead[len] = 0;
First the test should be >=
but again, such a value would be beyond the end of the target buffer.
Also consider that if you receive 8 or more characters, you will have no room for a terminating null in pwdReadBuffer, and so cannot pass it to anything that expects a null terminated string.
If you want to use null-terminate storage for a string of up to 8 bytes size, you need 9 bytes of storage. And of course you need to only use in-range indices to access the elements.
This behavior (where contents of pwdReadBuffer
print out the same as those of packetBuffer
) is occurring because you haven't properly null-terminated your strings.
After you copy the first 8 characters of packetBuffer
to pwdReadBuffer
the statement if (len > 8) pwdReadBuffer[len] = 0;
gets executed. It sets pwdReadBuffer[16]
to 0, ie, references out of array bounds.
Apparently lampCmdRead
is allocated directly after pwdReadBuffer
, so when you copy the next 8 characters of packetBuffer
to lampCmdRead
, they are being copied, in effect, to pwdReadBuffer[8] ... pwdReadBuffer[15]
, so that the println
prints a 16-character string,
2qZ@X51Rredledon
.
For each of your three arrays, allocate an extra byte for a null terminator.