Calling a function changes value of variable!?

Hello!

I have a code which shows some behaviour i did not really expect:

uint16_t* variable1 = getvalue("Var1");
uint16_t* variable2 = getvalue("Var2");
getvalue("Var1");
Serial.println(variable2);

What happens here: the serial monitor prints the value of getvalue("Var1"), just because it was called before.

How can calling a function override the value if not explicitely written down?

Best regards!

You code is a piece of trash.

Line1 & Line2 almost never work. Line3 does not do anything. Line4 prints trash.

Post your whole code in code tags please!

You must be making something up. This code will not even compile, since it is not possible to pass a uint16_t * value to Serial.println. You can't print pointers with Serial.println.

Provide real code that reproduces the problem.

Also, once you correct the code, it might turn out that the behavior depends on what you are doing inside getvalue. So, you should provide the definition of getvalue as well. We are not telepathic here.

This is actually the real code, I just renamed for simplicity and removed the calculations within getvalue().

I just need a simple way to return 2 numbers from a function, that's what the code is for.

Serial.println(variable2); actually gives a result, the compiler does not even complain about it, so i thought it's ok!

uint16_t* getvalue(const char *Parameter) { 
  static uint16_t Value[2];
  Value[0]=otherfunction();
  Value[1]=otherfunction();
  return Value;
}
void Function() {
  uint16_t* variable1 = getvalue("Var1");
  uint16_t* variable2 = getvalue("Var2");
  getvalue("Var1");
  Serial.println(variable2);
}
Serial.println(variable2);

this prints the address of variable2 which is an unsigned 16 bits number.

Please provide a complete code that actually compiles. Snippets are useless. If your code is large, cluttered, or poorly organized, post an MCVE.

Here’s the original code:

uint16_t* readbmpWidthHeight(const char *filename) { 
  
  File     bmpFile;
  static uint16_t WidthHeight[2];
  bmpFile = SD.open(filename);
  if (!bmpFile) {
    Serial.print(F("File not found"));
  }
  
  if(read16(bmpFile) == 0x4D42) { // BMP signature
    (void)read32(bmpFile);// Read & ignore file size
    (void)read32(bmpFile); // Read & ignore creator bytes
    (void)read32(bmpFile); // Read & ignore Start of image data
    (void)read32(bmpFile);// Read & ignore header size
    WidthHeight[0]= read32(bmpFile);
    WidthHeight[1]= read32(bmpFile);
  }
  bmpFile.close();
  return WidthHeight;
}
void Interface_Main() {
[color=red]  Serial.println(freeRam());
  uint16_t* confbmpWidthHeight = readbmpWidthHeight("conf.bmp");
  uint16_t* logobmpWidthHeight = readbmpWidthHeight("logo.bmp");
  readbmpWidthHeight("conf.bmp");
  Serial.println(logobmpWidthHeight[0]);[/color]

  Serial.println("In Main_Interface...");
  while (1) {
    TSPoint p;
    p = TouchScan();

    if (p.y > 10 && p.y < confbmpWidthHeight[1] + 10 &&
        p.x > 10 && p.x < confbmpWidthHeight[0] + 10) {

      Serial.println("Go into config mode");
      Build_Interface_Config();
      Interface_Config();
      return;
    }

    if (p.y > 100 && p.y < logobmpWidthHeight[1] + 100 &&
        p.x > 70 && p.x < logobmpWidthHeight[0] + 70) {
      Start_Program();
      return;
    }
  }
}

arduino_new:
this prints the address of variable2 which is an unsigned 16 bits number.

No, it prints the value for the previously called function. Maybe does it print from what it finds under this address, and this gets just overwritten from the function with a new value?

It still won't compile.

confbmpWidthHeight* and logobmpWidthHeight* are both pointing to the same memory address.

Your function is returning a pointer to its internal static buffer. Every call to that function returns a pointer to the same buffer. And every time you call that function it writes new values into that buffer.

In your code you are receiving and storing pointers to that static buffer. So, through those pointers you are seeing those values, which change every time you call the function.

All exactly as it should be.

Do not return pointers to internal static buffers. Or, if you have to do that for some reason, remember that your function will become non-reenterable and that the next call to the function will typically overwrite the data prepared by the previous call. Which is exactly what you are observing in your example.

Okay, I understood the problem with this code.

It seems then the function uses memory capacity even after it has been executed completely? Not what I have planned…

But how can I now save the values I need?

I unfortunately have no better way to realize this code. I tried before with std::pair to get 2 values from a function, but it’s not supported by standard as it would require to include .

I unfortunately have no better way to realize this code.

There undoubtedly is a better way, but since you have not clearly described what you are trying to do, it is doubtful that anyone here can help.

Create the separate arrays in the calling function. Pass a pointer to one of the arrays INTO the called function which then stores the data at the location specified by the pointer.

gfvalvo: Create the separate arrays in the calling function. Pass a pointer to one of the arrays INTO the called function which then stores the data at the location specified by the pointer.

Sounds good, ,may be simple to realize, but exceeds my programming skills anyway...

I am currently using global variables to save the value i need. Ugly solution, requires more RAM than necessary, but works for now.. :/

You can pass a parameter by reference. Declare the function like this...

void getBmpWidthHeight(const char *filename, uint32_t &width, uint32_t &height) {
  ...
    width= read32(bmpFile);
    height= read32(bmpFile);
  ...
}

Then call it like this...

void setup() {
  unsigned long w, h;
  getBmpWidthHeight("logo.bmp", w, h);

  Serial.print("Width = ");
  Serial.println(w);
}

Edit: fixed typo in "c0onst"

Thank you a lot for this example!!

Thanks to all af you for your help.

Cheers!