Determine the size of a C++ array programmatically?
delete []
does know the size that was allocated. However, that knowledge resides in the runtime or in the operating system's memory manager, meaning that it is not available to the compiler during compilation. And sizeof()
is not a real function, it is actually evaluated to a constant by the compiler, which is something it cannot do for dynamically allocated arrays, whose size is not known during compilation.
Also, consider this example:
int *arr = new int[256];
int *p = &arr[100];
printf("Size: %d\n", sizeof(p));
How would the compiler know what the size of p
is? The root of the problem is that arrays in C and C++ are not first-class objects. They decay to pointers, and there is no way for the compiler or the program itself to know whether a pointer points to the beginning of a chunk of memory allocated by new
, or to a single object, or to some place in the middle of a chunk of memory allocated by new
.
One reason for this is that C and C++ leave memory management to the programmer and to the operating system, which is also why they do not have garbage collection. Implementation of new
and delete
is not part of the C++ standard, because C++ is meant to be used on a variety of platforms, which may manage their memory in very different ways. It may be possible to let C++ keep track of all the allocated arrays and their sizes if you are writing a word processor for a windows box running on the latest Intel CPU, but it may be completely infeasible when you are writing an embedded system running on a DSP.
C find static array size
sizeof(theFruit) / sizeof(theFruit[0])
Note that sizeof(theFruit[0]) == sizeof(char *)
, a constant.
Is there any shortcut for array size / length in C?
You can use sizeof(array)/sizeof(*array)
and make a macro.
#define length(array) (sizeof(array)/sizeof(*(array)))
Size of an array is different in the main function and user-defined functions
You get that behaviour because, in the C language the function declaration
void printArraySize(int array[])
is equivalent to
void printArraySize(int *array)
And therefore the value of the line int size = sizeof(array) / sizeof(array[0]);
on a program compiled for 32-bit where sizeof(int) == 4
is always 1.
Arrays cannot be passed to functions as arrays, but as pointers. In fact, if you try to modify array
in the printArraySize
function you will modify it also in the caller function main
.
And that's why strings in C (and in many other programming languages) are 0-terminated.
how to get a length of char array char*
For starters you have to use the qualifier const in the array declaration.
const char * array[] = {"one","two","three","five"};
To get the number of elements in the array you can write
size_t n = sizeof( array ) / sizeof( *array );
If your compiler supports the C++ 17 Standard then you also can write
#include <iterator>
//...
size_t n = std::size( array );
Before the C++ 17 Standard you can use the structure std::extent
.
For example
#include <type_trats>
//...
size_t n = std::extent<decltype( array )>::value;
How can I change the size of an array in C?
Once an array in C has been created, it is set. You need a dynamic data structure like a Linked List or an ArrayList
Can I tell the size of an array created with new type[n] in C++?
The answer to the specific question is no, you cannot determine the length of the array pointed at by mymap
. The language simply provides no mechanism for that.
But if all you want to do is make sure that all the elements of the array are set to false
, then all you have to do is value initialize it:
bool* mymap = new bool[n]();
// ^^
Unfortunately, this only works for zero-like values for built-in types. There would be no equivalent way to set all the values to true
.
Creating an Array of known Dimensions, Type and Length Programmatically
You can use this overload of Array.CreateInstance
:
Array.CreateInstance(type, sizeOfDimensions);
Creates a multidimensional Array of the specified Type and dimension
lengths, with zero-based indexing. The dimension lengths are specified
in an array of 32-bit integers.
How can I get the size of an array from a pointer in C?
No, there is no way to get this information without depending strongly on the implementation details of malloc
. In particular, malloc
may allocate more bytes than you request (e.g. for efficiency in a particular memory architecture). It would be much better to redesign your code so that you keep track of n
explicitly. The alternative is at least as much redesign and a much more dangerous approach (given that it's non-standard, abuses the semantics of pointers, and will be a maintenance nightmare for those that come after you): store the lengthn
at the malloc'd address, followed by the array. Allocation would then be:
void *p = calloc(sizeof(struct mystruct) * n + sizeof(unsigned long int),1));
*((unsigned long int*)p) = n;
n
is now stored at *((unsigned long int*)p)
and the start of your array is now
void *arr = p+sizeof(unsigned long int);
Edit: Just to play devil's advocate... I know that these "solutions" all require redesigns, but let's play it out.
Of course, the solution presented above is just a hacky implementation of a (well-packed) struct. You might as well define:
typedef struct {
unsigned int n;
void *arr;
} arrInfo;
and pass around arrInfo
s rather than raw pointers.
Now we're cooking. But as long as you're redesigning, why stop here? What you really want is an abstract data type (ADT). Any introductory text for an algorithms and data structures class would do it. An ADT defines the public interface of a data type but hides the implementation of that data type. Thus, publicly an ADT for an array might look like
typedef void* arrayInfo;
(arrayInfo)newArrayInfo(unsignd int n, unsigned int itemSize);
(void)deleteArrayInfo(arrayInfo);
(unsigned int)arrayLength(arrayInfo);
(void*)arrayPtr(arrayInfo);
...
In other words, an ADT is a form of data and behavior encapsulation... in other words, it's about as close as you can get to Object-Oriented Programming using straight C. Unless you're stuck on a platform that doesn't have a C++ compiler, you might as well go whole hog and just use an STL std::vector
.
There, we've taken a simple question about C and ended up at C++. God help us all.
Related Topics
How to Printf Uint64_T? Fails With: "Spurious Trailing '%' in Format"
Metaprograming: Failure of Function Definition Defines a Separate Function
How to Get Std::Vector Pointer to the Raw Data
Include Header Files Using Command Line Option
Should I Use an Exception Specifier in C++
Foreach Macro on Macros Arguments
In Stl Maps, Is It Better to Use Map::Insert Than []
Explicit Specialization of Template Class Member Function
Efficient Implementation of Log2(_M256D) in Avx2
C++: Constructor Initializer For Arrays