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
-
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– Abel2021年08月01日 20:44:21 +00:00Commented Aug 1, 2021 at 20:44
-
@Abel There's no such thing as a C++ vector on Arduino - the STL is lacking.Majenko– Majenko2021年08月01日 20:56:13 +00:00Commented Aug 1, 2021 at 20:56
-
there are implementations that should work well enough. arduino.cc/reference/en/libraries/vectorAbel– Abel2021年08月01日 21:00:10 +00:00Commented Aug 1, 2021 at 21:00
-
@mehmet Please see my answer to a previous question: arduino.stackexchange.com/a/25317/22924John Burger– John Burger2021年09月02日 10:43:48 +00:00Commented Sep 2, 2021 at 10:43
2 Answers 2
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;
}
-
1just 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 timeLesto– Lesto2021年08月02日 10:14:05 +00:00Commented Aug 2, 2021 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– Majenko2021年08月02日 11:02:57 +00:00Commented Aug 2, 2021 at 11:02
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
}