Reputation: 419
I have a function that returns a pointer to a structure as the following :
//header file
typedef struct {
unsigned char *buffer;
uint8_t len;
} T_ABC_PACKET
in the main file, I create a pointer to a function and tries to print this
T_ABC_PACKET *pct = NULL;
pct = function_that_return_the_packet;
printf("value of packet is %s \n", pct->buffer);
the result is always consistent in the printing function. I expect the buffer to have an 8 byte, and the last byte is always a corrupted memory. value is 10000357`�2U
but if I print the buffer inside the function :
T_ABC_PACKET* function_that_return_the_packet {
T_ABC_PACKET *pct = NULL;
char string_temp[80];
//some more initialization...
pct->buffer = (unsigned char *)string_temp;
pct->len = 5;
printf("value of packet is %s \n", pct->buffer);
return pct;
}
the value printed in the function is 10000357f. Only the last character is corrupted. This always provide a consistent value, no many times I run the program, only the last character is corrupted in the caller of the function. I understand one possible case is memory leak, but I tried to check carefully and I can not find any leak. How do I get the pct->buffer to have everything correctly?
Upvotes: 0
Views: 221
Reputation: 158469
It looks like you are returning a pointer to a local variable which is undefined behavior, string_temp
is local to function_that_return_the_packet
and will not exist after you exit that function.
As Daniel suggested using strdup
is probably the simplest way to fix the problem:
pct->buffer = strdup(string_temp);
Just make sure you check that it did not fail. You could of course also use malloc
and then strcpy
.
Upvotes: 5
Reputation: 726539
Once you fix the undefined behavior of returning a pointer to local (see Shafik Yaghmour answer) you still have undefined behavior: it appears that the buffer is not null-ternminated, so %s
format specifier reads past it, and stops only when it finds an unrelated \0
.
If you know that the buffer's length cannot exceed eight, you can copy its content up to pct->len
into a char buffer, theninsert a terminator at the end:
char tmpBuf[9]; // max length is 8, plus one for null ternminator
memcpy(tmpBuf, pct->buffer, pct->len);
tmpBuf[pct->len] = '\0';
printf("value of packet is %s \n", tmpBuf);
Upvotes: 1
Reputation: 19956
This is the source of the problem:
pct->buffer = (unsigned char *)string_temp;
'string_temp' is allocated on the stack. When function returns, it is destroyed somewhere later, or not, as in your case, except last byte.
You should:
Use strdup()
instead of assignment in that line.
When you are done with whole structure, use free()
to release that string before releasing whole structure.
Upvotes: 0