2009-01-29 16:33:34 8 Comments
First off, here is some code:
int main()
{
int days[] = {1,2,3,4,5};
int *ptr = days;
printf("%u\n", sizeof(days));
printf("%u\n", sizeof(ptr));
return 0;
}
Is there a way to find out the size of the array that ptr
is pointing to (instead of just giving its size, which is four bytes on a 32-bit system)?
Related Questions
Sponsored Content
34 Answered Questions
[SOLVED] For-each over an array in JavaScript?
- 2012-02-17 13:51:48
- Dante1986
- 3925084 View
- 4462 Score
- 34 Answer
- Tags: javascript arrays loops foreach iteration
89 Answered Questions
[SOLVED] How do I remove a particular element from an array in JavaScript?
- 2011-04-23 22:17:18
- Walker
- 6169293 View
- 7695 Score
- 89 Answer
- Tags: javascript arrays
34 Answered Questions
[SOLVED] Create ArrayList from array
- 2008-10-01 14:38:32
- Ron Tuffin
- 1441440 View
- 3451 Score
- 34 Answer
- Tags: java arrays arraylist type-conversion
47 Answered Questions
[SOLVED] How to check if an object is an array?
- 2011-01-23 18:53:04
- mpen
- 1448462 View
- 2589 Score
- 47 Answer
- Tags: javascript arrays javascript-objects
37 Answered Questions
47 Answered Questions
[SOLVED] How do I check if an array includes a value in JavaScript?
- 2008-10-25 22:14:40
- brad
- 2419878 View
- 3798 Score
- 47 Answer
- Tags: javascript arrays algorithm time-complexity javascript-objects
10 Answered Questions
[SOLVED] Improve INSERT-per-second performance of SQLite?
- 2009-11-10 22:16:43
- Mike Willekes
- 384947 View
- 2889 Score
- 10 Answer
- Tags: c performance sqlite optimization
30 Answered Questions
[SOLVED] How to append something to an array?
- 2008-12-09 00:20:05
- interstar
- 3020211 View
- 2895 Score
- 30 Answer
- Tags: javascript arrays append
18 Answered Questions
[SOLVED] With arrays, why is it the case that a[5] == 5[a]?
- 2008-12-19 17:01:33
- Dinah
- 95277 View
- 1574 Score
- 18 Answer
- Tags: c arrays pointers pointer-arithmetic
10 Answered Questions
[SOLVED] Why are elementwise additions much faster in separate loops than in a combined loop?
- 2011-12-17 20:40:52
- Johannes Gerer
- 232957 View
- 2183 Score
- 10 Answer
- Tags: c++ c performance compiler-optimization vectorization
13 comments
@baz 2017-03-11 11:56:01
In strings there is a
'\0'
character at the end so the length of the string can be gotten using functions likestrlen
. The problem with an integer array, for example, is that you can't use any value as an end value so one possible solution is to address the array and use as an end value theNULL
pointer.@Fabio says Reinstate Monica 2017-03-11 12:16:38
Your code is full of comments, but I think it would make everything easier if you added some general explanation of how this works outside of code, as normal text. Can you please edit your question and do it? Thank you!
@Peter Cordes 2018-06-19 03:03:09
Creating an array of pointers to each element so you can linear-search it for
NULL
is probably the least efficient alternative imaginable to just storing a separatesize
directly. Especially if you actually use this extra layer of indirection all the time.@Tᴏᴍᴇʀ Wᴏʟʙᴇʀɢ 2018-06-22 11:42:34
You can do something like this:
@DigitalRoss 2016-07-25 20:50:19
There is no magic solution. C is not a reflective language. Objects don't automatically know what they are.
But you have many choices:
@Shivangi Chaurasia 2016-07-10 10:32:16
Size of days[] is 20 which is no of elements * size of it's data type. While the size of pointer is 4 no matter what it is pointing to. Because a pointer points to other element by storing it's address.
@Amitābha 2016-12-27 04:33:11
sizeof(ptr) is the size of pointer and sizeof(*ptr) is the size of pointer to which
@SKD 2016-03-15 11:22:40
No, you can't use
sizeof(ptr)
to find the size of arrayptr
is pointing to.Though allocating extra memory(more than the size of array) will be helpful if you want to store the length in extra space.
@user4713908 2015-10-05 14:45:29
My solution to this problem is to save the length of the array into a struct Array as a meta-information about the array.
But you have to care about set the right length of the array you want to store, because the is no way to check this length, like our friends massively explained.
@user3065147 2014-03-11 08:27:39
array_size is passing to the size variable:
Usage is:
@Ryan 2009-01-29 17:12:46
For dynamic arrays (malloc or C++ new) you need to store the size of the array as mentioned by others or perhaps build an array manager structure which handles add, remove, count, etc. Unfortunately C doesn't do this nearly as well as C++ since you basically have to build it for each different array type you are storing which is cumbersome if you have multiple types of arrays that you need to manage.
For static arrays, such as the one in your example, there is a common macro used to get the size, but it is not recommended as it does not check if the parameter is really a static array. The macro is used in real code though, e.g. in the Linux kernel headers although it may be slightly different than the one below:
You can google for reasons to be wary of macros like this. Be careful.
If possible, the C++ stdlib such as vector which is much safer and easier to use.
@Sanjaya R 2009-01-29 17:19:28
ARRAY_SIZE is a common paradigm used by practical programmers everywhere.
@Ryan 2009-01-29 17:27:51
Yes it is a common paradigm. You still need to use it cautiously though as it is easy to forget and use it on a dynamic array.
@Paul Tomblin 2009-01-29 17:40:44
Yes, good point, but the question being asked was about the pointer one, not the static array one.
@newacct 2013-02-28 18:52:43
That
ARRAY_SIZE
macro always works if its argument is an array (i.e. expression of array type). For your so-called "dynamic array", you never get an actual "array" (expression of array type). (Of course, you can't, since array types include their size at compile-time.) You just get a pointer to the first element. Your objection "does not check if the parameter is really a static array" is not really valid, since they are different as one is an array and the other isn't.@Natalie Adams 2013-04-23 02:24:50
There is a template function floating around that does the same thing but will prevent the use of pointers.
@Ryan 2013-04-24 14:55:31
@newacct I think you are getting caught up in semantics. My point was simply that macros do not have type checking. If you pass a pointer to the macro, you will not get the intended result. If you can use the C++ template equivalent, it is safer -- but the OP asked about C.
@fnisi 2018-05-16 21:05:41
The
ARRAY_SIZE
macro, with a different name, is used in K&R C 2nd edition. Not a good practice nowadays, but the language itself does not offer a solution.@jxh 2013-04-09 17:21:56
As all the correct answers have stated, you cannot get this information from the decayed pointer value of the array alone. If the decayed pointer is the argument received by the function, then the size of the originating array has to be provided in some other way for the function to come to know that size.
Here's a suggestion different from what has been provided thus far,that will work: Pass a pointer to the array instead. This suggestion is similar to the C++ style suggestions, except that C does not support templates or references:
But, this suggestion is kind of silly for your problem, since the function is defined to know exactly the size of the array that is passed in (hence, there is little need to use sizeof at all on the array). What it does do, though, is offer some type safety. It will prohibit you from passing in an array of an unwanted size.
If the function is supposed to be able to operate on any size of array, then you will have to provide the size to the function as additional information.
@Max 2013-08-17 01:12:10
+1 for "You cannot get this information from the decayed pointer value of the array alone" and providing a workaround.
@Paul Tomblin 2009-01-29 16:39:57
No, you can't. The compiler doesn't know what the pointer is pointing to. There are tricks, like ending the array with a known out-of-band value and then counting the size up until that value, but that's not using sizeof.
Another trick is the one mentioned by Zan, which is to stash the size somewhere. For example, if you're dynamically allocating the array, allocate a block one int bigger than the one you need, stash the size in the first int, and return ptr+1 as the pointer to the array. When you need the size, decrement the pointer and peek at the stashed value. Just remember to free the whole block starting from the beginning, and not just the array.
@viki.omega9 2013-03-03 19:19:55
I'm sorry for this posting a comment so late but if the compiler does not know what the pointer is pointing to how does free know how much memory to clear? I do know that this information is stored internally for functions like free to use. So my question is why can' the compiler do so too?
@Paul Tomblin 2013-03-03 20:48:57
@viki.omega9, because free discovers the size at runtime. The compiler can't know the size because you could make the array a different size depending on runtime factors (command line arguments, contents of a file, phase of moon,etc).
@viki.omega9 2013-03-03 22:52:44
Quick follow up, why isn't there a function that can return the size the way free does?
@Paul Tomblin 2013-03-03 23:11:31
Well, if you could guarantee that the function was only called with malloced memory and the library tracks the malloced memory the way most I've seen do (by using an int before the returned pointer) then you could write one. But if the pointer is to a static array or the like, it would fail. Similarly, there is no guarantee that the size of malloced memory is accessible to your program.
@RouteMapper 2013-11-15 18:10:32
Isn't this a problem if the pointer isn't inside any allocated memory at all? We would never be able to find the out-of-band value nor would we be able to find the stashed size of the array. Am I off here?
@Paul Tomblin 2013-11-15 18:31:35
@RouteMapper, there are lots of problems with the "tricks". That's why I called them tricks. The language doesn't provide robust support for finding out the side of an allocated array, and it's going to be up to you to find the solution that works for your use-case.
@RouteMapper 2013-11-15 18:40:09
@PaulTomblin, do you think there's a better way to do it in an intermediate language? Say, LLVM IR?
@Zan Lynx 2014-07-20 03:48:32
@viki.omega9: Another thing to keep in mind is that the size recorded by the malloc/free system may not be the size you asked for. You malloc 9 bytes and get 16. Malloc 3K bytes and get 4K. Or similar situations.
@Dhruv Mullick 2015-02-01 14:11:04
@PaulTomblin: Can you explain what the difference between days and ptr is? Both of them are integer pointers which contain the address to the first element of the array.
@Lightness Races with Monica 2015-03-14 15:21:03
Have a badge.
@Jon Wheelock 2015-10-14 08:08:14
Is it possible if we pass the pointer to entire array like char (*ptr)[size] ? In this case ptr is defined as char (*ptr)[size] = &days;. But I am not sure how we get the size inside the function.
@Paul Tomblin 2015-10-14 12:30:31
@JonWheelock no, that won't help. The pointer does not retain the size information.
@skurton 2012-04-19 11:53:43
There is a clean solution with C++ templates, without using sizeof(). The following getSize() function returns the size of any static array:
Here is an example with a foo_t structure:
Output:
@WorldSEnder 2014-06-04 09:43:44
I have never seen the notation
T (&)[SIZE]
. Can you explain what this means? Also you could mention constexpr in this context.@Oguk 2014-10-12 07:02:09
That's nice if you use c++ and you actually have a variable of an array type. Neither of them is the case in the question: Language is C, and the thing the OP wants to get the array size from is a simple pointer.
@user2796283 2016-08-28 10:43:57
would this code lead to code bloat by recreating the same code for every different size/type combination or is that magically optimised out of existence by the compiler?
@Peter Cordes 2018-06-19 02:53:14
@WorldSEnder: That's C++ syntax for a reference of array type (with no variable name, just a size and element-type).
@Peter Cordes 2018-06-19 02:55:04
@user2796283: This function is optimized away entirely at compile time; no magic is needed; it's not combining anything to a single definition, it's simply inlining it away to a compile-time constant. (But in a debug build, yes, you'd have a bunch of separate functions that return different constants. Linker magic might merge ones that use the same constant. The caller doesn't pass
SIZE
as an arg, it's a template param that has to already be known by the function definition.)@zett42 2018-10-31 14:05:07
As of C++17, we have
std::size()
, which is similar to yourgetSize()
function and in addition has an overload for containers, that provide asize()
member function.@Zan Lynx 2009-01-29 16:42:28
The answer is, "No."
What C programmers do is store the size of the array somewhere. It can be part of a structure, or the programmer can cheat a bit and malloc() more memory than requested in order to store a length value before the start of the array.
@dsm 2009-01-29 16:44:30
Thats how pascal strings are implemented
@Adam Naylor 2010-07-14 19:48:42
and apparently pascal strings are why excel runs so fast!
@Zan Lynx 2010-07-14 19:52:28
@Adam: It is fast. I use it in a list of strings implementation of mine. It is super-fast to linear search because it is: load size, prefetch pos+size, compare size to search size, if equal strncmp, move to next string, repeat. It's faster than binary search up to about 500 strings.
@David 2011-04-13 21:04:15
For this specific example, yes, there is, IF you use typedefs (see below). Of course, if you do it this way, you're just as well off to use SIZEOF_DAYS, since you know what the pointer is pointing to.
If you have a (void *) pointer, as is returned by malloc() or the like, then, no, there is no way to determine what data structure the pointer is pointing to and thus, no way to determine its size.
Output: