hi falks, I need to figure out some annoying thing.
I have a function returning char*
char* A(...)
{
char res[150] = "";
//here res is filled with some other text
return res;
}
//......
{
char* B = A(...);
//some code using B
char* C = A(...);
// B is spoiled!!!
}
char* returned by A is used somewhere else. While previous result B is being used function A is called once again. And here I get some strange behaviour. Old B returned previously seems to be overwritten by a new call.
Here is original function A:
char* sim300::read(uint16_t timeout)
{
uint32_t tick = millis();
char buf[150] = "";
while ((gsm->available()) || (millis() - tick < timeout))
{
char a = gsm->read();
if ((a != -1) && (a != '\0') && (a != '\r') && (a != '\r'))
{
size_t len = strlen(buf);
buf[len++] = a;
buf[len] = '\0';
}
}
return buf;
}
When a function ends, the memory statically (ie not with malloc) gets destroyed and reused. So if you pass a pointer to that memory to somewhere else, it will be a pointer to memory whose existence is not guaranteed. So you should make the char buffer then pass a pointer to it to A like this:
void A(char* res...)
{
//here res is filled with some other text
}
//......
{
char B[150] = "";
A(B, ...);
//some code using B
char C[150] = "";
A(C, ...);
}
Who said you can't rely on it?
If the memory is static or allocated from the heap, no problem, but never expect to return a pointer to memory in a stack frame.
Then what is return type char* for if I can not rely on it?
Imagine cutting a bunch of arrows out of foam board. On each one, write the name of a part of your body. Tape them to the wall of your office/classroom/whatever, pointing to the relevant parts of your body when you are standing against the wall.
If someone comes in and follows the pointer to left elbow, they can find your left elbow, right?
Those arrows are equivalent to the pointers in your code.
Now, you go home at the end of your class/workday. That is the equivalent of the function ending.
Do those arrows taped on the wall still point to parts of your body? Of course not.
Now suppose one of those arrows said desk on it, and pointed at the desk. You leave to go home, and that pointer still points to your desk, right? So, that pointer is sill valid. You can rely on it.
Pointers need to point to things that are NOT going to go away at the end of a function.
What you need to do is look at reference variables, rather than pointers. In the caller, define an array, and pass a reference to that array to the function. The function can then modify the contents, but not the address of, that array. The function then doesn't need to return anything.
In the caller, define an array, and pass a reference to that array to the function. The function can then modify the contents, but not the address of, that array. The function then doesn't need to return anything.
pass a reference like WizenedEE said?
void A(char* res...)
{
//here res is filled with some other text
}
//......
{
char B[150] = "";
A(B, ...);
//some code using B
char C[150] = "";
A(C, ...);
}