21

Code for dynamic array by entering size and storing it into "n" variable, but I want to get the array length from a template method and not using "n".

int* a = NULL;   // Pointer to int, initialize to nothing.
int n;           // Size needed for array
cin >> n;        // Read in the size
a = new int[n];  // Allocate n ints and save ptr in a.
for (int i=0; i<n; i++) {
    a[i] = 0;    // Initialize all elements to zero.
}
. . .  // Use a as a normal array
delete [] a;  // When done, free memory pointed to by a.
a = NULL;     // Clear a to prevent using invalid memory reference.

This code is similar, but using a dynamic array:

#include <cstddef>
#include <iostream>
template< typename T, std::size_t N > inline
std::size_t size( T(&)[N] ) { return N ; }
int main()
{
     int a[] = { 0, 1, 2, 3, 4, 5, 6 };
     const void* b[] = { a, a+1, a+2, a+3 };
     std::cout << size(a) << '\t' << size(b) << '\n' ;
}
Mario Cervera
  • 671
  • 1
  • 8
  • 19
evergreen
  • 7,771
  • 2
  • 17
  • 25

1 Answers1

48

You can't. The size of an array allocated with new[] is not stored in any way in which it can be accessed. Note that the return type of new [] is not an array - it is a pointer (pointing to the array's first element). So if you need to know a dynamic array's length, you have to store it separately.

Of course, the proper way of doing this is avoiding new[] and using a std::vector instead, which stores the length for you and is exception-safe to boot.

Here is what your code would look like using std::vector instead of new[]:

size_t n;        // Size needed for array - size_t is the proper type for that
cin >> n;        // Read in the size
std::vector<int> a(n, 0);  // Create vector of n elements initialised to 0
. . .  // Use a as a normal array
// Its size can be obtained by a.size()
// If you need access to the underlying array (for C APIs, for example), use a.data()

// Note: no need to deallocate anything manually here
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • 3
    Not sure I understand why this has been downvoted. Actually, I'm sure I don't... – Lightness Races in Orbit Feb 25 '14 at 08:48
  • @LightnessRacesinOrbit Same here. Perhaps somebody thought I should have looked for that duplicate instead of answering? – Angew is no longer proud of SO Feb 25 '14 at 08:51
  • 3
    I've observed a strong correlation between no good reason to downvote and no comment/suggestion to improve/fix the answer. – juanchopanza Feb 25 '14 at 08:54
  • @juanchopanza Not to sound repetitive, but same here :-) – Angew is no longer proud of SO Feb 25 '14 at 08:56
  • now how to define and use vector method for dynamic array and get size? – evergreen Feb 25 '14 at 08:58
  • @evergreen: You don't need to define it. `vector` already has a `size()` member function; call that when you want to know the size. – Mike Seymour Feb 25 '14 at 09:05
  • 1
    @evergreen I've expanded the answer with how your code would look with `std::vector` instead of `new[]` – Angew is no longer proud of SO Feb 25 '14 at 09:09
  • http://www.cplusplus.com/reference/vector/vector/ and get size http://www.cplusplus.com/reference/vector/vector/size/ – evergreen Feb 25 '14 at 09:23
  • 3
    And you might as well say it: the way you spell "dynamic array" in C++ is `std::vector`, _not_ `T* array = new T[]`. One can't stress enough that there is never a reason to use array new (or at least almost never---but I've been using C++ for more than 20 years, and I've never found a case where array new was appropriate). – James Kanze Feb 25 '14 at 09:32
  • @JamesKanze +1. Though I believe implementing `std::vector` *might* be a use case for `new[]`. – Angew is no longer proud of SO Feb 25 '14 at 09:42
  • 1
    @Angew Any reasonable vector class (and the standard requires it of `std::vector`) will separate allocation and initialization, probably be using the `std::operator new()` function and placement new. Otherwise, you end up having to default construct all of the elements, and then assign to them, rather than constructing them with the desired initializer immediately. (When I first started C++, there wasn't a `std::vector`, and of course, the first thing one did was write your own vector and string classes.) – James Kanze Feb 25 '14 at 09:59
  • @JamesKanze Right, excellent point about the allocation-init separation. So it seems I've run out of ideas for use of `new[]` as well. – Angew is no longer proud of SO Feb 25 '14 at 10:09
  • You know, I was thinking about this some. It is said that under the hood, when you use `new []`, c++ stores the length in a sort of hidden prefixed value in front of the array and then gives you the pointer to the first element just after the length. It does this so that it can `delete []` it later. But why the heck would we not be able to access that length?! – Andrew Jun 23 '21 at 13:25
  • Traditionally, a dynamic array is something like this "mystruc* ptr = new mystruct[100];" and not vectors which are part of the standard library which is only recently part of C++ compiler so that might explain some downvotes. – Jack D Menendez Feb 05 '23 at 07:46