C++ Sizeof(Array) Return Twice the Array's Declared Length

c++ sizeof(array) return twice the array's declared length

sizeof returns the size of a variable (in this case, your arrays), where sizeof(char) is 1. Since a char is one byte wide, sizeof returns the size of the variable in bytes. Since each short int is two bytes wide on your system, an array of 6 of them will have size 12, and an array of 13 will have size 26.

Array larger than specified size in C++

sizeof doesn't return the number of elements in the array, it returns the memory size in bytes. Since your array contains three regular integers, and integers are 4 bytes in size, that's 3 * 4 == 12 bytes.

To get the length of the array, you have a few options:



Option 1

int size = sizeof(test) / sizeof(test[0]);

What that does is get the size of the array (which is 12 bytes) then divides that by the size of a single element (which is 4 bytes). Obviously 12 / 4 == 3.



Option 2

As pointed out by @PaulMcKenzie, if you're able to use C++17 you can use std::size. That makes it very easy because you can just do this:

int size = std::size(test);


Option 3 (Not recommended)

int size = *(&test + 1) - test;

Which is a clever hack using pointers, explained here. Will result in undefined behaviour and may break, depending on the compiler and its optimisations.

How do I determine the size of my array in C?

Executive summary:

int a[17];
size_t n = sizeof(a)/sizeof(a[0]);

Full answer:

To determine the size of your array in bytes, you can use the sizeof
operator:

int a[17];
size_t n = sizeof(a);

On my computer, ints are 4 bytes long, so n is 68.

To determine the number of elements in the array, we can divide
the total size of the array by the size of the array element.
You could do this with the type, like this:

int a[17];
size_t n = sizeof(a) / sizeof(int);

and get the proper answer (68 / 4 = 17), but if the type of
a changed you would have a nasty bug if you forgot to change
the sizeof(int) as well.

So the preferred divisor is sizeof(a[0]) or the equivalent sizeof(*a), the size of the first element of the array.

int a[17];
size_t n = sizeof(a) / sizeof(a[0]);

Another advantage is that you can now easily parameterize
the array name in a macro and get:

#define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))

int a[17];
size_t n = NELEMS(a);

Why is this code outputting so many numbers?

sizeof(a) is not the length of the array, it is the number of bytes required to store it.

Since the element type of the array is larger than one byte each, the numbers are different.

Can sizeof() be used to define an array length?

The sizeof expression is evaluated at compile time (by the compiler not the preprocessor) so the expression is legal.

There's an exception to this rule in C99 where dynamic arrays are allowed. In that case sizeof is, depending on context, evaluated at runtime (http://en.wikipedia.org/wiki/Sizeof). It doesn't change the legality of the expression in the question.

Array size bigger than elements stated

sizeof(ar);

returns the size of an array in bytes. To get the number of elements, you need to divide by the size of each element:

int numElt = sizeof(ar) / sizeof(ar[0]);

C arrays offer a lot of surprises, you should usually use std::array or std::vector instead.

C sizeof a passed array

There is no magic solution. C is not a reflective language. Objects don't automatically know what they are.

But you have many choices:

  1. Obviously, add a parameter
  2. Wrap the call in a macro and automatically add a parameter
  3. Use a more complex object. Define a structure which contains the dynamic array and also the size of the array. Then, pass the address of the structure.

Do I need to put sizeof after array length in malloc?

Both are valid, but many veteran programmers will prefer the way you did it.

The advantage of using sizeof *array as opposed to sizeof(int) is that if you happen to change the type of array then you don't need to change how you do the allocation.

There's also no technical reason to multiply by length first instead of the element size. If anything, when looking at a call to malloc the first thing you want to know is how many "things" you're allocating, so from a readability standpoint putting the length first might make more sense. On the other hand, because the result of the sizeof operator is unsigned, putting it first guarantees that the math is done with unsigned types if you have multiple array dimensions.

You also don't want to cast the return value of malloc as that can mask other errors in your code, specifically a missing #include <stdlib.h>

How do sizeof(arr) / sizeof(arr[0]) work?

If you have an array then sizeof(array) returns the number of bytes the array occupies. Since each element can take more than 1 byte of space, you have to divide the result with the size of one element (sizeof(array[0])). This gives you number of elements in the array.

Example:

std::uint32_t array[10];

auto sizeOfInt = sizeof(std::uint32_t); // 4
auto numOfBytes = sizeof(array); // 10*sizeOfInt = 40
auto sizeOfElement = sizeof(array[0]); // sizeOfInt = 4
auto numOfElements = sizeof(array) / sizeof(array[0]); // numOfBytes / sizeOfElement = 40 / 4 = 10

LIVE EXAMPLE

Note that if you pass an array to a function, the above won't work since the array decays to a pointer and sizeof(array) returns the size of the pointer.

std::size_t function(std::uint32_t a[]) // same for void function(std::uint32_t a[10])
{
return sizeof(a); // sizeof(std::uint32_t*)!
}

std::uint32_t array[10];
auto sizeOfArray = function(array); // array decays to a pointer inside function()

LIVE EXAMPLE #2



Related Topics



Leave a reply



Submit