0
int * a;
a = new int[10];
cout << sizeof(a)/sizeof(int);

if i would use a normal array the answer would be 10, alas, the lucky number printed was 1, because sizeof(int) is 4 and iszeof(*int) is 4 too. How do i owercome this? In my case keeping size in memory is a complicated option. How do i get size using code?

My best guess would be to iterate through an array and search for it's end, and the end is 0, right? Any suggestions?

--edit

well, what i fear about vectors is that it will reallocate while pushing back, well you got the point, i can jus allocate the memory. Hoever i cant change the stucture, the whole code is releevant. Thanks for the answers, i see there's no way around, so ill just look for a way to store the size in memory.

what i asked whas not what kind of structure to use.

Ben
  • 3,989
  • 9
  • 48
  • 84
  • 1
    Why are you using a magic number `10` in the first place? Would it not be easier to define a constant and reuse it? – Grambot Jan 18 '13 at 21:33
  • Nope, the only arrays that end in a zero by default are string literals. – Mooing Duck Jan 18 '13 at 21:33
  • I think the key to this question is understanding why keeping size in memory is a complicated option. I mean, not using the heap is understandable, but not having a constant on the stack is a fairly draconian restriction, one that I can't imagine a use for. Can you elaborate? – Matt Jan 18 '13 at 21:37
  • 4
    "How do i owercome this?" Don't use a pointer in the first place. use `std::vector a(10);`, then `a.size()`. Or `std::array` if you want it fixed-length. And for any further questions about pointer usage for objects, [read this](http://dl.dropbox.com/u/6101039/Modern%20C%2B%2B.pdf) – WhozCraig Jan 18 '13 at 21:38
  • no. thank you, i cant change the structure. – Ben Jan 18 '13 at 21:45
  • Just click on the checkbox next to the answer you found most helpful. And answers that tell you that you can't do what you want to do are still valid answers if they're correct. Just because you didn't get the answer you wanted doesn't mean your question wasn't answered. – Omnifarious Jan 18 '13 at 21:58

3 Answers3

7

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:

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:

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;
Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Yes, i wrote that too, thats why i'm looking for another option. – Ben Jan 18 '13 at 21:33
  • i mean, yea, i know i can't do that – Ben Jan 18 '13 at 21:34
  • @BenediktasRimantasJacikeviiu: Another option is added already! – Nawaz Jan 18 '13 at 21:34
  • @BenediktasRimantasJacikeviiu: Made the answer shorter and to the point :D – Nawaz Jan 18 '13 at 21:37
  • there are reasons i will not use a vector or any other type of structure but int * a: the program is calculating performance. what about the plan B? to cycle through an array until the end is found, how do i do that? – Ben Jan 18 '13 at 21:42
  • 1
    @BenediktasRimantasJacikeviiu there is no "end" unless you maintain a relationship between `N` (the length you allocated) and the pointer itself. And for someone that is worried about performance, walking to the "end" of *anything* is an O(N) operation, while "give me the length because you know it already" queries to a sequence container like `std::vector<>` via `a.size()` are O(1). – WhozCraig Jan 18 '13 at 21:45
  • 2
    @BenediktasRimantasJacikeviiu: There is essentially no performance penalty for using `::std::vector` if you set the size you need in the constructor. – Omnifarious Jan 18 '13 at 21:47
  • @BenediktasRimantasJacikeviiu: What do you think? that `std::vector` and `std::array` will kill the performance of your application? If you think so, then you're mistaken. They're not slow. You must experiment with them in order to form any opinion about them. – Nawaz Jan 18 '13 at 21:48
  • well, what i fear about vectors is that it will reallocate while pushing back, well you got the point, i can jus allocate the memory. Hoever i cant change the stucture, the whole code is releevant. Thanks for the answers, i see there's no way around, so ill just look for a way to store the size in memory. – Ben Jan 18 '13 at 21:56
  • @BenediktasRimantasJacikeviiu do you *own* both the allocation (the code here) and the deallocation of this array of `ints` ? – WhozCraig Jan 18 '13 at 22:00
  • @BenediktasRimantasJacikeviiu: Added some alternatives, which are not that great! – Nawaz Jan 18 '13 at 22:04
  • +1 (long time ago): The one significant downside to alternative #2 is the storage class must be able to support integral magnitude that represents the length of the array. `Foo *arFoo = new[ N ]` is still a problem, but for `int`, `unsigned`, `long`, etc, it is not unheard of to resort to this technique at all. – WhozCraig Jan 18 '13 at 22:12
  • @WhozCraig: Of course, for class type, you cannot use the second alternatives. Alternatives are usually task-specific anyway. – Nawaz Jan 18 '13 at 22:19
2

sizeof(a) is going to be the size of the pointer, not the size of the allocated array.

There is no way to get the size of the array after you've allocated it. The sizeof operator has to be able to be evaluated at compile time.

How would the compiler know how big the array was in this function?

void foo(int size)
{
    int * a;
    a = new int[size];
    cout << sizeof(a)/sizeof(int);
    delete[] a;
}

It couldn't. So it's not possible for the sizeof operator to return the size of an allocated array. And, in fact, there is no reliable way to get the size of an array you've allocated with new. Let me repeat this there is no reliable way to get the size of an array you've allocated with new. You have to store the size someplace.

Luckily, this problem has already been solved for you, and it's guaranteed to be there in any implementation of C++. If you want a nice array that stores the size along with the array, use ::std::vector. Particularly if you're using new to allocate your array.

#include <vector>

void foo(int size)
{
    ::std::vector<int> a(size);
    cout << a.size();
}

There you go. Notice how you no longer have to remember to delete it. As a further note, using ::std::vector in this way has no performance penalty over using new in the way you were using it.

Omnifarious
  • 54,333
  • 19
  • 131
  • 194
  • Guys, as i wrote in question, i know i can't do this, the question is: is there another way around? – Ben Jan 18 '13 at 21:36
  • @BenediktasRimantasJacikeviiu: Use `::std::vector`, that's what it's there for. To answer your question, there is absolutely no reliable way to get the size of an array that's been allocated. You have to store it someplace. – Omnifarious Jan 18 '13 at 21:37
0

If you are unable to use std::vector and std::array as you have stated, than your only remaning option is to keep track of the size of the array yourself.

I still suspect that your reasons for avoiding std::vector are misguided. Even for performance monitoring software, intelligent uses of vector are reasonable. If you are concerned about resizing you can preallocate the vector to be reasonably large.

0-0
  • 482
  • 4
  • 11