1

I'm working on an Arduino project and I need to use HMC5883L sensor's libraries. The problem is that the libraries are kind old and my compiler is complaining about the 'return' from a function:

/home/leandro/arduino-1.6.1/libraries/HMC5883L/HMC5883L.cpp: In member function 'uint8_t* HMC5883L::Read(int, int)':
/home/leandro/arduino-1.6.1/libraries/HMC5883L/HMC5883L.cpp:124:11: warning: address of local variable 'buffer' returned [-Wreturn-local-addr]
uint8_t buffer[length];

The part of the code is:

HMC5883L.cpp

uint8_t* HMC5883L::Read(int address, int length)
{
  Wire.beginTransmission(HMC5883L_Address);
  Wire.write(address);
  Wire.endTransmission();

  Wire.beginTransmission(HMC5883L_Address);
  Wire.requestFrom(HMC5883L_Address, length);

  uint8_t buffer[length]; // Here is line 124
  if(Wire.available() == length)
  {
      for(uint8_t i = 0; i < length; i++)
      {
          buffer[i] = Wire.read();
      }
  }
  Wire.endTransmission();

  return buffer;
}

HMC5883L.h:

#ifndef HMC5883L_h
#define HMC5883L_h

#include <Arduino.h>
#include <Wire.h>

#define HMC5883L_Address 0x1E
#define ConfigurationRegisterA 0x00
#define ConfigurationRegisterB 0x01
#define ModeRegister 0x02
#define DataRegisterBegin 0x03

#define Measurement_Continuous 0x00
#define Measurement_SingleShot 0x01
#define Measurement_Idle 0x03

#define ErrorCode_1 "Entered scale was not valid, valid gauss values are: 0.88, 1.3, 1.9, 2.5, 4.0, 4.7, 5.6, 8.1"
#define ErrorCode_1_Num 1

struct MagnetometerScaled
{
    float XAxis;
    float YAxis;
    float ZAxis;
};

struct MagnetometerRaw
{
    int XAxis;
    int YAxis;
    int ZAxis;
};

class HMC5883L
{
    public:
      HMC5883L();

      MagnetometerRaw ReadRawAxis();
      MagnetometerScaled ReadScaledAxis();

      int SetMeasurementMode(uint8_t mode);
      int SetScale(float gauss);

      const char* GetErrorText(int errorCode);

    protected:
      void Write(int address, int byte);
      uint8_t* Read(int address, int length);

    private:
      float m_Scale;
};
#endif

I tried few suggestions from here, here and here without success. Maybe I just couldn't figure out on how to solve this issue using those suggestion.

EDIT: There was an typo on my code, just changed it.

2
  • 1
    I can't believe that this is really code which was provided in a library. uint8_t *buffer[length]; is complete broken. First it is an array of pointers and not an array and it is allocated on the stack of the function and later returned which never works. Commented May 6, 2015 at 16:51
  • My mistake, I was performing some tests and I left this behind. I edited my post with the correct code. Commented May 6, 2015 at 16:53

3 Answers 3

4

Solution 1

Instead of

uint8_t buffer[length]; // Here is line 124

Use:

// Allocate memory from the heap.
uint8_t* buffer = new unit8_t[length];

Make sure to deallocate the memory in the calling function.

Solution 2

Expect the input to come from the calling function.

uint8_t* HMC5883L::Read(int address, int length, uint8_t buffer[])
Sign up to request clarification or add additional context in comments.

1 Comment

There needs to be a check to verify there is only one allocation of the buffer inside the function. Try calling the function 2 times and verify.
2

It is because you declare buffer on the stack. If you want to return a dynamically allocated buffer, use malloc:

uint8_t *buffer = new uint8_t[length];
if (buffer == NULL) error_allocation;

// Make sure to de-allocate after you finish to use it
delete [] buffer;

4 Comments

Where's the malloc call in your example?
My mistake, I was performing some tests and I left this behind. I edited my post with the correct code.
How does your example prevent multiple allocations of the buffer? Remember, the memory can't be deleted until after the function exits.
It is C++, so one must use new and delete keywords : arduino.land/FAQ/content/4/20/en/…. And it does not prevent memory to be allocated twice, but it is up to the programmer to take care of this.
1

A simple solution is to modify the library files and declare the buffer as static. The static keyword tells the compiler that the variable will live after the execution leaves the function. Since it lives after exiting the function, the address will still be valid.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.