How to find the size of dynamic array
Ah this is experimental code. Interesting things are there.
- You will allocate memory for
N
integers whereN
is between0
to10
including0
and10
. Then you applied
sizeof
to the pointer (int*
) and what it points to (int
). It won't matter how much memory you allocate. The output from this line will be same.There is no error check here. if it was you couldn't tell whether it is successful entirely surely because
rand()
may give0
as result. You need to store it somewhere and check whether it is0
because on that casemalloc
may or may not returnNULL
.Printing what
sizeof
returns should be done using%zu
format specifier. It returnssize_t
.
- To be more clear remember it is a pointer pointing to dynamically allocated memory.
RandomArray
is not an array - it is an pointer pointing to contiguous memory. That doesn't make it array. It is still a pointer. And thesizeof
trick that you wanted to apply thinkingRandomArray
is an array won't work. In general we keep track of it - using some variable. But here you don't know how much memory you allocated.
malloc
may returnNULL
when you pass0
to it. Handle that case separately. In case you getsz!=0
and getNULL
inRandomArray
throw error.size_t sz = rand()%11;
RandomArray = malloc(sz);
if(!RandomArray && sz){
perror("malloc");
exit(EXIT_FAILURE);
}
After all this talk - the short answer is, with this setup there is no use of the code (code you have written) so far. You don't know what rand()
returned on that case inside malloc.
How to get dynamic array's size in C?
In your example table
has type struct date *
. So when you use the sizeof
operator on it you get the size of the pointer.
There is no portable way to determine how much available space a pointer to allocated memory points to. You need to keep track of that yourself.
Find the size of a dynamically allocated array
How can we print the first dimension of this 2d array (3)?
You have to keep track of the number of elements you allocated in a separate variable:
size_t num_elements = 3;
char **a = malloc( sizeof *a * num_elements );
if ( a )
{
a[0] = "asd"; // NOTE: these lines store the addresses of the string
a[1] = "fghj"; // literals in a[0], a[1], and a[2] - you are not copying
a[2] = "klzxc"; // the *contents* of each string, just its address
}
...
for ( size_t i; i < num_elements; i++ )
printf( "a[%zu] = %s\n", i, a[i] );
A pointer, regardless of type, points to (stores the address of) a single object. That single object may be the first in a larger sequence of objects, but there is no way to determine that from pointer value itself. If you have the following:
char ** char * char
+---+ +---+ +---+---+---+---+
a:| | ---> | | a[0] -----> |'a'|'s'|'d'| 0 |
+---+ +---+ +---+---+---+---+
| | a[1] ---+
+---+ | +---+---+---+---+---+
| | a[2] -+ +-> |'f'|'g'|'h'|'j'| 0 |
+---+ | +---+---+---+---+---+
|
| +---+---+---+---+---+---+
+---> |'k'|'l'|'z'|'x'|'c'| 0 |
+---+---+---+---+---+---+
You cannot know from a
itself that it points to the first of 3 objects; you cannot know from each a[i]
itself that it points to a sequence of char
objects. That information must be tracked separately. In the case of a
we have a separate variable, num_elements
, that keeps track of how may elements are in a
. In the case of each a[i]
, we have the string terminator to tell us how long each string is.
What should I do to get the size of a 'dynamic' array?
When I pass a 'static' array to sizeof(), it returns the dimension of the declared array multiplied by the number of bytes that the datatype uses in memory.
Correct, that is how the size of the entire array is computed.
However, a dynamic array seems to be different.
This is because you are not passing a dynamic array; you are passing a pointer. Pointer is a data type with the size independent of the size of the block of memory to which it may point, hence you always get a constant value. When you allocate memory for your dynamically sized memory block, you need to store the size of allocation for future reference:
size_t count = 123; // <<== You can compute this count dynamically
int *array = new int[count];
cout << "Array size: " << (sizeof(*array) * count) << endl;
C++14 will have variable-length arrays. These arrays will provide a proper size when you check sizeof
.
Could it be related to the following? [...]
No, it is unrelated. Your code snippet shows undefined behavior (writing past the end of the allocated block of memory), meaning that your code is invalid. It could crash right away, lead to a crash later on, or exhibit other arbitrary behavior.
C dynamically growing array
I can use pointers, but I am a bit afraid of using them.
If you need a dynamic array, you can't escape pointers. Why are you afraid though? They won't bite (as long as you're careful, that is). There's no built-in dynamic array in C, you'll just have to write one yourself. In C++, you can use the built-in std::vector
class. C# and just about every other high-level language also have some similar class that manages dynamic arrays for you.
If you do plan to write your own, here's something to get you started: most dynamic array implementations work by starting off with an array of some (small) default size, then whenever you run out of space when adding a new element, double the size of the array. As you can see in the example below, it's not very difficult at all: (I've omitted safety checks for brevity)
typedef struct {
int *array;
size_t used;
size_t size;
} Array;
void initArray(Array *a, size_t initialSize) {
a->array = malloc(initialSize * sizeof(int));
a->used = 0;
a->size = initialSize;
}
void insertArray(Array *a, int element) {
// a->used is the number of used entries, because a->array[a->used++] updates a->used only *after* the array has been accessed.
// Therefore a->used can go up to a->size
if (a->used == a->size) {
a->size *= 2;
a->array = realloc(a->array, a->size * sizeof(int));
}
a->array[a->used++] = element;
}
void freeArray(Array *a) {
free(a->array);
a->array = NULL;
a->used = a->size = 0;
}
Using it is just as simple:
Array a;
int i;
initArray(&a, 5); // initially 5 elements
for (i = 0; i < 100; i++)
insertArray(&a, i); // automatically resizes as necessary
printf("%d\n", a.array[9]); // print 10th element
printf("%d\n", a.used); // print number of elements
freeArray(&a);
Determine the length of a dynamic array after creation time in C
p
is a pointer, sizeof(p)
is not the size of the array that was allocated by malloc()
, it is just the size of the pointer itself, which may be 4 or 8 depending on the platform (among other more exotic possibilities).
The expression sizeof(a) / sizeof(a[0])
only works for arrays, defined as int a[10];
or possibly with a length determined at compile time from the intializer: int a[] = { 0, 2, 4 };
.
There is no portable way to retrieve the size of the block allocated by malloc()
from the pointer. You must keep track of the size separately.
Related Topics
How to Use Unordered_Set with Custom Types
How to Load a Bmp on Glut to Use It as a Texture
Is Casting Std::Pair<T1, T2> Const& to Std::Pair<T1 Const, T2> Const& Safe
C++ Templates: Conditionally Enabled Member Function
Accessing Static Member Through Invalid Pointer: Guaranteed to "Work"
Why Do Lambda Functions Drop Deduced Return Type Reference by Default
Incomplete Class Usage in Template
Forward Declaration with Vector of Class Type - Pointer to Incomplete Class Type Not Allowed
Open File with Fopen, Given Absolute Path on Windows
Using Boost Adaptors with C++11 Lambdas
Iterator Adapter to Iterate Just the Values in a Map
How to Call a Pointer-To-Member-Function
Is It More Efficient to Copy a Vector by Reserving and Copying, or by Creating and Swapping
Why Does Pointer to Int Convert to Void* But Pointer to Function Convert to Bool