0

I have been searching about how to get the size of an array decayed as a pointer but most search results seem to explain what decay is and how to prevent it. Below is the code explaining the problem

void print_size(int y[]){
    cout<<"sizeof(y) = "<<sizeof(y)<<"\tsizeof(y[0]) = "<<sizeof(y[0])<<"\tnum elements = "<<sizeof(y)/sizeof(y[0])<<endl;
}
main(){
    int x[20] = {1,2,3,4};
    cout<<"sizeof(x) = "<<sizeof(x)<<"\tsizeof(x[0]) = "<<sizeof(x[0])<<"\tnum elements = "<<sizeof(x)/sizeof(x[0])<<endl;;
    print_size(x);
    
}

The output of the above code is

sizeof(x) = 80 sizeof(x[0]) = 4 num elements = 20
sizeof(y) = 8 sizeof(y[0]) = 4 num elements = 2

The problem in the second output is obviously due to the array decaying into a pointer. Is there any way we can get the size and number of elements in an array after decaying happens?

Muhammad Adeel Zahid
  • 17,474
  • 14
  • 90
  • 155
  • 8
    *After* decaying happens? No. By definition, once it's a pointer, it doesn't have array size information. – Nelfeal Nov 14 '22 at 12:03
  • It is called *decaying* (though not officially) because information has been lost. Once lost, that information (the array's size) cannot be retrieved. – Adrian Mole Nov 14 '22 at 12:07
  • 1
    Not an official part of the language standard, but you can read the `size_t` (typically 4 or 8) bytes appearing right before the pointed address and find out. Many heap implementations store the size of the allocated block right "before" where the block starts. But again, this is platform (compiler) specific, and not dictated by the C++ language standard. So TLDR, something like `size_t size = *((size_t*)x)-1);`. –  Nov 14 '22 at 12:08
  • just avoid C arrays and use `std::array` with a template function instead for static-sized arrays, or pass the size explicitly – phuclv Nov 14 '22 at 12:09
  • 1
    This (my suggestion above) might fail depending on the alignment of `x` to begin with (again depending on your platform - compiler and/or HW). So under specific platforms, you might need to go a bit further and calculate the first size_t-aligned address appearing before the address of `x` in memory. –  Nov 14 '22 at 12:12
  • 2
    Be aware that arrays are a C construct and should be avoided in C++. They literally have no advantage and lots of disadvantages. [``](https://en.cppreference.com/w/cpp/container/vector) by default, [``](https://en.cppreference.com/w/cpp/container/array) if you *really* need the static size. – DevSolar Nov 14 '22 at 12:14
  • @bbbbbbbbb its undefined behavior. It might work or it might not. Anyhow OPs array is not dynamically allocated. – 463035818_is_not_an_ai Nov 14 '22 at 12:31
  • Thank you everyone for the response. @bbbbbbbbb so there is no proper way in the language specifications to access the array size once it has been decayed. – Muhammad Adeel Zahid Nov 14 '22 at 12:32
  • I will move with other options like or as specified by @DevSolar – Muhammad Adeel Zahid Nov 14 '22 at 12:32
  • 2
    @MuhammadAdeelZahid `void print_size(int y[])` is the same as `void print_size(int* y)` and an `int*` is a pointer to a single `int`. It has no information on the array. – 463035818_is_not_an_ai Nov 14 '22 at 12:33
  • @463035818_is_not_a_number Yes, in this example the array is not dynamically allocated but in practice, I would like to read a line of integers from a file separated by commas and creating an array for it – Muhammad Adeel Zahid Nov 14 '22 at 12:34
  • https://stackoverflow.com/a/1120224/4117728 – 463035818_is_not_an_ai Nov 14 '22 at 12:35
  • @bbbbbbbbb -- arrays can be created on the stack (as in the code in the question), so there doesn't have to be a memory manager involved; even if you know for sure how your memory manager stores size information (which you don't), you can't rely on that information being present. – Pete Becker Nov 14 '22 at 14:56

0 Answers0