TL;DR: Solutions 1 and 2 are both bad.
The way you wrote the example makes malloc useless since you know the size of ans and buf at compile-time, if those are really known at compile-time then , just don't use malloc at all, declare variables on the stack. In C, generally avoid dynamic memory allocation as much as possible and prefer to create buffers which can hold the maximum size a buffer can have in your application. That avoids this kind of problems in the first place. The way you wrote the example makes malloc
useless since you know the size of ans
and buf
at compile-time. The only place where dynamic memory allocation can be useful is for buffers whose sizes are unknown at compile-time, but you can still avoid it (see below). If buf
is an incoming message, and ans
the answer to this message, the size of ans
can be unknown at compile-time, at least if you use variable-length messages.
Your version 2 is not working and can not work! First you declared ans
to be an array of size 1 and iterate over it until index 2(now you edited that). Second to declare the array ans
as global you would need to know its size at compile-time, and then of course if you knew its size at compile-time you would just declare the array ans
in the function checkSerial
. Moreover, when you declare a variable which is used by several functions in C don't forget to declare it static, otherwise it can be accessed from all files in your project.
A solution avoiding dynamic allocation, notice you avoid the disadvantages of your 2 solutions: the pointer to pointer and the global variable, and moreover your program can not leak since you don't use dynamic allocation:
enum {MSG_MAX_SIZE = 256 };
typedef struct message {
uint8_t payload[MSG_MAX_SIZE];
size_t msg_size;
} message_t;
void checkSerial(const message_t *buf, message_t *ans)
{
//parse buf and determine size of answer
...
...
//fill answer payload
ans->msg_size = buf[42];
}
int main(void)
{
while (1) {
message_t buf;
getMsg(&buf);
message_t ans;
checkSerial(&buf, &ans);
}
}