Getting Size of Array from Pointer C++

How to find the 'sizeof' (a pointer pointing to an array)?

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.

size of array of pointers

The output of the following program will give you some hints and understanding about the size of a type and a pointer to a type.

#include <stdio.h>

int main(void)
{
int p1[10];
int *p2[10];
int (*p3)[10];

printf("sizeof(int) = %d\n", (int)sizeof(int));
printf("sizeof(int *) = %d\n", (int)sizeof(int *));
printf("sizeof(p1) = %d\n", (int)sizeof(p1));
printf("sizeof(p2) = %d\n", (int)sizeof(p2));
printf("sizeof(p3) = %d\n", (int)sizeof(p3));

return 0;
}

int p[10]; => 10 consecutive memory blocks (each can store data of type int) are allocated and named as p

int *p[10]; => 10 consecutive memory blocks (each can store data of type int *) are allocated and named as p

int (*p)[10]; => p is a pointer to an array of 10 consecutive memory blocks (each can store data of type int)

Now coming to your question:

>> in the first code p points to an array of ints.
>> in the second code p points to an array of pointers.

You are correct. In the code:2, to get the size of the array where p points to, you need to pass the base address

printf("%d", (int)sizeof(p));

and not the following

printf("%d", (int)sizeof(*p));   //output -- 4

The following are equivalent:

*p, *(p+0), *(0+p), p[0]

>> what's the difference between p[10] and 
>> (*p)[10]...they appear same to me...plz explain

The following is the answer to your other question:

int p[10];
_________________________________________
| 0 | 1 | 2 | | 9 |
| (int) | (int) | (int) | ... | (int) |
|_______|_______|_______|_________|_______|


int (*p)[10]
_____________________
| |
| pointer to array of |
| 10 integers |
|_____________________|

Get array length by pointer

What you get is actually what is expected to happen. With

int *pnarr;
sizeof (pnarr);

you get the size of a int* pointer, that is an address (usually 4 or 8 bytes depending on your system architecture). You get it whatever address yiu assign to it.


The arr_len () function you posted in the question will not find the length of the array, because it wrongly assumes that the last element is 0. That is usually not true.

That is done instead with strings (char arrays), which actually are chars terminated by a 0. But in that case it is a standatd, and you are sure that the string won't contain zeros in the middle of it.


In conclusion, if you need the total size in bytes of the array, you can get it from the original array name with

sizeof(narr)

If you need the number of elements of the array, instead, just use

sizeof(narr)/sizeof(narr [0])

So you can't do it with the pointer but you need the original array "reference".

Get length of an Array using a pointer

The easy answer is no, you cannot. You'll probably want to keep a variable in memory which stores the amount of items in the array.

And there's a not-so-easy answer. There's a way to determine the length of an array, but for that you would have to mark the end of the array with another element, such as -1. Then just loop through it and find this element. The position of this element is the length. However, this won't work with your current code.

Pick one of the above.

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 arrInfos 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.

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);

How to get the length of an array from a pointer?

You can't, I'm afraid. You need to pass the length of the array to anyone who needs it. Or you can use a std::array or std::vector or similar, which keep track of the length themselves.

Pointer to an array get size C++

Simple.

Use std::vector<int> Or std::array<int, N> (where N is a compile-time constant).

If you know the size of your array at compile time, and it doens't need to grow at runtime, then use std::array. Else use std::vector.

These are called sequence-container classes which define a member function called size() which returns the number of elements in the container. You can use that whenever you need to know the size. :-)

Read the documentation:

  • std::array with example
  • std::vector with example

When you use std::vector, you should consider using reserve() if you've some vague idea of the number of elements the container is going to hold. That will give you performance benefit.

If you worry about performance of std::vector vs raw-arrays, then read the accepted answer here:

  • Is std::vector so much slower than plain arrays?

It explains why the code in the question is slow, which has nothing to do with std::vector itself, rather its incorrect usage.


If you cannot use either of them, and are forced to use int*, then I would suggest these two alternatives. Choose whatever suits your need.

struct array
{
int *elements; //elements
size_t size; //number of elements
};

That is self-explanatory.

The second one is this: allocate memory for one more element and store the size in the first element as:

int N = howManyElements();
int *array = int new[N+1]; //allocate memory for size storage also!
array[0] = N; //store N in the first element!

//your code : iterate i=1 to i<=N

//must delete it once done
delete []array;


Related Topics



Leave a reply



Submit