hannescam/NeoSPI

Small bug in show()

Opened this issue · 1 comments

while (cntCol < sizeof(col) / sizeof(col.at(0))) { // Count through all 24 bytes of the raw SPI color value for the current LED

Here this code likely does the right thing but for very wrong reasons :

vector<uint8_t> col(24); // And a new raw SPI data value
int cntTotal = 0; // Counter initializations
int cntCol = 0;
...
while (cntCol < sizeof(col) / sizeof(col.at(0))) { 
  ...
}

this gives:

while (cntCol < (24 / 1)). But the reason sizeof(col) is 24 is not because it was initialized with 24 bytes : most likely you'll be able to confirm that

std::vector<uint8_t> vec_small(10);
std::vector<uint8_t> vec_big(10000);
std::cout << sizeof(vec_small) << " " << sizeof(vec_big) << "\n" ;

also prints 24 24.. that's because sizeof(x) returns the "C" size of the class, not the logical size / number of elements in the container... and it happens that std::vector is implemented with three pointers:

template<typename T>
struct vector { 
    T* begin;
    T* end;
    T* capacity;
};

and on 64 bit systems, sizeof(T*) == 8 bytes, thus 8 * 3 == 24 and sizeof(vector) == 24 for any std::vector instance no matter how many elements there are.
except...

  • on 32 bit systems it would actually be 12
  • with safety features such as address sanitizer or CHERI it may be bigger

thus I'd really recommend to just spell out

while (cntCol < col.size()) { 
  ...
}

or even directly

while (cntCol < 24) { 
  ...
}

as it's never supposed to not be 24 from the code

Thankyou for pointing this out!
I noticed this too a few days ago because I am in the middle of a rewrite for this library but I moved it to GitLab (I forgot to mention this in the README)
And I will include this fix in the rewrite