Go Down

Topic: Memory problem while calling same function multiple times (Read 513 times) previous topic - next topic

Raptor5

Nov 18, 2012, 07:25 pm Last Edit: Nov 18, 2012, 07:28 pm by Raptor5 Reason: 1
hi falks, I need to figure out some annoying thing.
I have a function returning char*
Code: [Select]

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:
Code: [Select]
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;
}



Am I doing something wrong?

WizenedEE

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:
Code: [Select]

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, ...);
}

Raptor5

Then what is return type char* for if I can not rely on it?

AWOL

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.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

fungus


Then what is return type char* for if I can not rely on it?


You can. The question you need to ask is "where is res"?

Try "Serial.println(B)" and "Serial.println(C)"...

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

PaulS

Quote
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.

Raptor5

Quote
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?

Code: [Select]
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, ...);
}


Already done. Thank you sooo much!

Go Up