5

Having a variable declared like this:

double *variable;

which I think is pretty the same that writing

double variable[];

and then some methods working on it;

how is it possible to obtain the length of the array of double? What I mean is, how do I know in which position lies the last inizialized / accessed / written element of variable ?

Andreas DM
  • 10,685
  • 6
  • 35
  • 62
Paynomindtous
  • 71
  • 1
  • 2
  • 7
  • 4
    A pointer is not an array. Also, arrays are dumb as they do not know their own size. Use `std::vector` or `std::array` instead. – PaulMcKenzie Jul 02 '15 at 09:19
  • But `double varialble[]` can actually be a pointer in some situations. So, it depends *where* you're writing it. – juanchopanza Jul 02 '15 at 09:20
  • You may find some info [here][1] hope it helps. [1]: http://stackoverflow.com/questions/4108313/how-do-i-find-the-length-of-an-array – IMP Jul 02 '15 at 09:22
  • Check this [link](http://stackoverflow.com/questions/4108313/how-do-i-find-the-length-of-an-array) out. If possible use `STL` containers like `std::vector`, to put it simple, it's the fancy C++ way of an array, with `iterators` and functions like `.size()`. – Mäx Müller Jul 02 '15 at 09:22
  • So writing *variable; or variable[] is completely not the same thing? – Paynomindtous Jul 02 '15 at 09:25
  • @Paynomindtous I think you're getting confused when seeing the syntax used to access elements (both using `[ ]`), and thus believing that pointers and arrays are the same thing. There is a big difference if you *declare* a pointer and when you *declare* an array as opposed to *accessing* the elements. – PaulMcKenzie Jul 02 '15 at 09:26

3 Answers3

7

The main difference is that:

  • double* variable; is a pointer meant to be dynamically allocated during execution (via new or malloc for instance), or may point to a double object (then, it's not an "array").
  • double variable[]; is an array statically allocated (so it's size is defined and fixed during compilation). Note that double variable[]; is not valid as a declaration. Size of the array must be specified (double variable[20]; for instance).

To answer your question: you cannot determine the number of elements of a double* or double[] variable, unless you saved it somewhere yourself.

For instance, if you want to pass the double* object to a function, you'll need to pass both pointer and size (number of elements). Function proptotype is then ( double* data, size_t size ).

size_t mySize = 20;
double* data = new double[20];
callFunc( data, mySize );
delete [] data; // need to be deleted because dynamically allocated

or:

static const size_t mySize = 20;
double data[mySize];
callFunc( data, mySize );
// no need to be deleted because statically allocated

As commented by other users, prefer a std::vector which encapsulate a double* pointer and it's number of elements (among other attributes):

std::vector<double> data;
data.assign( 20, 0.0 );
callFunc( data );

callfunc can then access data values and know it's size using data.size().

Note: For char*, convention is to end up the string by a special character (\0), so, in this case, you can determine the size of the char array by finding this special character (that's what strlen does). You could do something similar with a double* pointer (like having a NaN to identifiy the last item and then recover the array size), but that would just be a hack and is nor conventional, nor recommended.

jpo38
  • 20,821
  • 10
  • 70
  • 151
  • you should also mention that `double* a` is not at all the same as `double a[]` (not only because of size and allocation, but first might be just a pointer). I mean it is mentioned in the comments, but i think it would make your answer a bit nicer. – 463035818_is_not_an_ai Jul 02 '15 at 09:51
  • "double* variable; is a pointer meant to be dynamically allocated " - in fact it may point to any instance of a `double` – M.M Jul 02 '15 at 11:00
1

Let me correct you.

double* foo;

declares a pointer to a double, named foo.

double foo[] = {1.1, 2.2, 3.3};

declares an array of doubles named foo, for which no memory has yet been allocated. Leftover from C++'s C's roots, is the fact that an array can decay to a pointer. So it is possible to do the following:

double foo[] = {1.1, 2.2, 3.3};
double bar* = foo[0];  // bar now points to the first element of foo.

But this is does not mean that foo and bar are the same thing. You can use a pointer to iterate over the contents of a c-array (assuming you know the size), , but there are subtle areas where the difference could trip you up (e.g. below).

You could also do something like:

double *foo;
// call something that allocates memory for an array and assigned the address of the first element to foo.

But in that case you are going to have to keep track of the array size yourself. That's why in C++, if you are using a statically allocated array, you should prefer std::array, and if you are using a dynamically allocated array, you should prefer std::vector, as these classes will handle the details better than you are likely to.

There is a cute way, which I don't recommend you use, but is an illustration of the differnece between double* and double foo[], which Scott Meyers talks about in "Effective Modern C++":

template <typename T, std::size_t N>
constexpr std::size_t arraySize(T (&)[N]) noexcept
{
    return N;
}

double foo[] = {1.1, 2.2, 3.3};
constexpr int array_size = arraySize(foo);

Will create a c-array with 3 doubles, and initialize the const_expr (it could be a variable, i used const_expr to make it explicit that this is deduced at compile time) array_size to the size of your array.

But avoid all that if you can and use std::array and std::vector when you can.

Spacemoose
  • 3,856
  • 1
  • 27
  • 48
1

Pointers are not arrays.

The code below is an array of size 4:

double arr[] {1.1, 1.2, 1.3, 1.4};

arr refers to a block of memory for example:

0x22fe20 | 0x22fe28 | 0x22fe30 | 0x22fe38 | 0x22fe40

While the below is pointing to the address of the beginning of arr:

double *p_arr {arr};

how is it possible to obtain the length of the array of double?

To get the size you can take the size of arr and devide it by the size of the first element:

size_t arr_len = (sizeof(arr) / sizeof(*arr));

Then, we know that the last initialized element is arr_len - 1.


Instead of manually finding the size ourselves, it's better and safer to use a std::vector:

std::vector<double> arr {1.1, 1.2, 1.3, 1.4};
std::cout << arr.size();
Andreas DM
  • 10,685
  • 6
  • 35
  • 62