0

well I am trying to get array size to convert hex value to int value. but if I try to get size of array it returns every time 2. Actually .I dont understand. how to get array size, can you help me?

this is my code

unsigned long w;

void setup() {
  Serial.begin(9600);

  uint8_t * packet = read_packet();
  Serial.println(sizeof(packet)); // PROMLEM IS HERE, IT RETURNS EVERYTIME "2"

  for (int i = 0; i < 4; i++)
  {
    Serial.println(packet[i]); //if i print the packet array all elements are here
  }

  /*
    for (byte i = 0; i < sizeof packet; i++) {
      w = w + ((long)(packet[sizeof packet - (i + 1)]) << (i * 8));
    }

  */
}

void loop() {
  // put your main code here, to run repeatedly:

}

uint8_t *read_packet() {
  static uint8_t buffer[4];

  buffer[0] = 0x00;
  buffer[1] = 0x32;
  buffer[2] = 0x32;
  buffer[3] = 0x32;

  Serial.println(sizeof buffer);
  return buffer;
}

if I print the packet array, all 4 elements are there 0,50,50,50. but size of array returns every time "2". even if I increase the array size.

maybe you can think why am I using pointers? because of my previous question answer is using this method. Read serial with header and end marker

4
  • sizeof is a compile-time item reporting the bytes something takes. In this case that means the bytes that the numeric value of pointer itself uses. If you allocate memory yourself, you'll have to store that separately. Consider using a c++ vector.
    – Abel
    Aug 1 at 20:44
  • @Abel There's no such thing as a C++ vector on Arduino - the STL is lacking.
    – Majenko
    Aug 1 at 20:56
  • there are implementations that should work well enough. arduino.cc/reference/en/libraries/vector
    – Abel
    Aug 1 at 21:00
  • @mehmet Please see my answer to a previous question: arduino.stackexchange.com/a/25317/22924 Sep 2 at 10:43
4

A pointer is just a pointer. It's not an array. On 8 bit Arduinos the memory address range is a 16 bit value, so a pointer will always be 2 bytes.

You need to return two values from your function - the buffer pointer and the length of the buffer. This is usually done by passing an extra integer pointer parameter:

unsigned long w;

void setup() {
  Serial.begin(9600);

  uint8_t plen;
  uint8_t * packet = read_packet(&plen); // Pass the pointer to the plen variable to store the length in

  Serial.println(plen); // This now prints "4"

  for (int i = 0; i < plen; i++) // You can now use `plen` here
  {
    Serial.println(packet[i]); //if i print the packet array all elements are here
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}

uint8_t *read_packet(uint8_t *len) {

  static uint8_t buffer[4];

  buffer[0] = 0x00;
  buffer[1] = 0x32;
  buffer[2] = 0x32;
  buffer[3] = 0x32;

  if (len != NULL) *len = 4; // Store 4 in the length variable if provided

  return buffer;
}
2
  • 1
    just a quick add: since arduino uses C++, it is possible to use reference to array uint8_t (&buffer)[4] to pass actual array and have sizeof working properly, and template to automatically have non-fixed size array, and maintain compile-time check for size and sizeof-like functions working properly, even with static_assert. Extremely powerful to control what size of array a function can process all at compile time
    – Lesto
    Aug 2 at 10:14
  • 1
    @Lesto Sure. But that implies some level of knowledge on the part of the programmer to even know what a reference or a template is... And this is Arduino...
    – Majenko
    Aug 2 at 11:02
1

Majenko's answer explains things and shows how to fix your code, but the solution with static buffer inside the function is not common.

Common is to have int readBuffer(unit8_t* buffer, size_t size).

The parameters are the buffer provided by the caller and the size of that buffer. The return value is the count of bytes written by the function into the buffer.

Real example:

int WiFiEspAtBuffStream::read(uint8_t* data, size_t size) {
  if (size == 0 || !available())
    return 0;

  size_t l = rxBufferLength - rxBufferIndex;
  if (l == 0 && size > rxBufferSize) // internal buffer is empty and provided buffer is large
    return EspAtDrv.recvData(linkId, data, size); // fill the large provided buffer directly

  // copy from internal buffer
  fillRXbuffer();
  for (size_t i = 0; i < l && i < size; i++) {
    data[i] = rxBuffer[rxBufferIndex++];
  }
  if (size <= l) // provided buffer was filled
    return size;
  return l + read(data + l, size - l); // handle the rest of provided buffer
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.