Every time you press a key on your keyboard, a key code gets sent from the keyboard to the computer. These are called ASCII codes. The keycode for a zero is 48, for 1 it's 49, 2 is 50, and so on. So, assuming msg[3] is the character '2', the expression:
msg[2] - '0'
resolves to:
msg[2] - '0'
'2' - '0'
50 - 48
2
Therefore, subtracting the ASCII key code for zero from any numeric digit character gives you that character as a numeric.
Finally, give up on the conversions on msg[]. Instead, if you can't assuming the incoming message is a null-terminated character array, try this:
char msg[7];
int len;
memset(msg, '\0', 7); // Set all elements to null
len = udp.read(msg,7);
// msg[len] = '\0'; // You could do away with memset() statement if the
// read() call does return the message length.
value = atoi(&msg[3]);
You said that the number can never be more than 255, so at most, you need 7 characters: "SR1255", or 6 plus one for the null termination character. The memset() call sets all elements to null, so you know whatever comes in has a null at the end of the array. Get rid of malloc() and free(), they just aren't a real good idea if they can be avoided.