0

I'm confused with a lot of answers found about what is a simple thing in other languages. I would like to get a reference to an object contained in class or struct. I've come up to using one of two different functions (here - getData()).

Question:

So, I am not sure which one to use, they appear to do the same thing. Other thing, is there some reason I should care because it's a union? And the most important question here is - I'm not sure about delete part I found in some answers, which scares me that this code example I've shown is not complete and will cause some memory leaks at some point.

#include <iostream>
#include <stdint.h>

using namespace std;

class settings_t {
  private:
  static const  long b1 =0;
    uint8_t setmap;
  public:
    uint8_t myBaseID; 
    uint8_t reserved1;
    uint8_t reserved2;
};  

class test1 {
  public: //actually, I want this to be private
    long v1;
    settings_t st;
    union {
      uint8_t data[4];
      uint32_t m1;
      settings_t st1;
    };
  public:
    uint8_t * getData() {
      return data;
    }
    uint8_t (&getData2())[4] {
      return data;
    }
};

int main() {
  test1 t1;
  t1.data[2]=65;
  uint8_t *d1 = t1.getData();
  cout<<" => " << d1[2];
  d1[2]=66;
  uint8_t *d2 = t1.getData2();
  cout<<" => " << d2[2];
}
Community
  • 1
  • 1
nekitip
  • 357
  • 1
  • 2
  • 10
  • A reference to an array will automatically convert to a pointer to the type of the array elements. That's what happens when you do `uint8_t *d2 = t1.getData2()`. If you use `auto` instead of `uint8_t *` you'd see the difference. – Mark Ransom Nov 21 '17 at 23:10
  • @George is it really undefined behavior? It's returning a reference to a member of an object that still exists. – Mark Ransom Nov 21 '17 at 23:11
  • Don't mess around with raw pointers or raw arrays. I'm pretty sure even on arduino there are better constructs supported like [advised here](https://stackoverflow.com/questions/46991224/are-there-any-valid-use-cases-to-use-new-and-delete-with-modern-c). – user0042 Nov 21 '17 at 23:22
  • One option is to return one byte at a time `uint8_t getData(int i) { return data[i]; }` – Bo Persson Nov 21 '17 at 23:41
  • 2
    BTW, don't worry about memory leaks in your code. For every ``new`` you should add a matching ``delete`` operator, but you don't have any ``new``s. – bjhend Nov 21 '17 at 23:57
  • @MarkRansom `auto` will do the same; `auto& d2 = t1.getData2();` is required to avoid decay – M.M Nov 21 '17 at 23:57
  • Union aliasing is not supported in ISO C++. not sure about arduino tho – M.M Nov 21 '17 at 23:58

1 Answers1

1

The main difference of c++ from languages like c# or java is that it does not provide you with built in memory management (not a managed language). So, if the program allocates memory in c++, it is a responsibility of the program to release the memory when it is not needed. so, delete in your answers is based on this requirement.

However in you case, the getData() function returns a pointer to the data which is a part of the class test1. This is an array and the array will exist as long as the object of this class exist. Both versions of the getData will work.

You did not use any dynamic data allocation, the object t1 of type test1 was allocated on the stack of the main function and would exist till your program exits. You should not worry about 'delete'.

The difference between two methods you use is that the first method does not care about the array size it returns, whether the other does. For that reason the second methods has very limited practical use, but provides better syntactic checking.

Serge
  • 11,616
  • 3
  • 18
  • 28
  • I think I understand. Just to clarify - the thing that it all happens in `main()`is not relevant? That is- if instead of in `main`() (ends with program ending), everything is done exactly the same in some other function, will it be the same? E.g. if there is no `new`, you don't need `delete`? – nekitip Nov 22 '17 at 07:53
  • Yes, `delete` usually means that there was`new`. – Serge Nov 22 '17 at 14:21