2

I'm trying to find the size of an array, and sizeof isn't working properly presumably because my array is a pointer, not an actual array (then again, I'm probably wrong). I'm new to C++, but not to programming.

Here's my function:

int getSizeOfPointerArray(int a[]){
    int n=0;
    while(true){
        if(!a[n]){
            cout << "a[" << n << "] doesn't exist, breaking" << endl;
            break;
        }
        cout << "a[" << n << "] exists with value " << a[n] << " at memory address " << &a[n] << endl;
        n++;
    }
    return n;
}

The function was called with the argument p where p was:

p = new (nothrow) int[f];

'f' was 3. The elements of the array were collected with:

for(n=0;n<f;n++){
    string c = ((n!=f-1)?", ":" ");
    cout << p[n] << c;
}

I was expecting to see the memory locations of the three elements of the array printed in the output - each four apart - and it to say that a[4] doesn't exist. Instead, it printed six memory addresses. The first three values were correct (all 3s), but the last three were -33686, -1414812757 and another -1414812757.

Why is this? Can I just divide the end result by 2, or is there not always double the elements you assigned? Is this the same with non-dynamic arrays?

5
  • 1
    Where are you calling getSizeOfPointerArray? How are you initializing the array? Is the last element of the array supposed to be 0? Sample code should be complete and self-contained, in addition to being concise. And you're right that sizeof (when called on a pointer to an array) won't return the size of an array, it returns the size of the pointer. Commented Jan 30, 2011 at 10:14
  • stackoverflow.com/questions/381621/… Commented Jan 30, 2011 at 10:14
  • @outis: I showed that the array was initialized with p = new (nothrow) int[f]; Commented Jan 30, 2011 at 10:20
  • You may want to read the FAQ about using arrays in C++ ;) Commented Jan 30, 2011 at 11:39
  • that allocates the array, but doesn't initialize the values in it. According to the standards, the initial value of dynamically allocated region is unspecified. Some implementations may zero-initialize it, but many won't perform any initialization at all. Commented Jan 30, 2011 at 11:49

4 Answers 4

7

When you allocate an "array" with new, you're just being given some arbitrary memory location that isn't currently being used by anything else. That memory (and its surroundings) are most likely filled with random junk, and probably not zeros. Writing known non-zero values to p[0], p[1] and p[2] will not affect the junk that lives just outside p.

So your loop is just walking along through memory, until it either happens to hit a zero (which I guess happened in this case), or it hits memory it's not allowed to access, which would result in a seg-fault.

As others have stated, if you're using C++, you should take advantage of the STL container classes. std::vector is probably the best replacement for a straightforward array.

Sign up to request clarification or add additional context in comments.

Comments

5

The size of a dynamically allocated array is not accessible to C++ code, I would recommend using an std::vector.

If the array is defined on the stack (e.g. int arr[2]; or int arr[] = { 1, 2, 3 }) then sizeof(arr) will be the sizeof(int) * elements_in_arr (even then you should prefer to use std::tr1::array). If you want to deal with an array whose size isn't known at compile time then 101% of the time std::vector is the way to go (plus or minus 2 percent).

1 Comment

Thanks to this and other answers, I've worked out what C++ programmers know that I didn't - Lua tables are not the same as C++ arrays. I used that technique based on Lua iteration, which would loop through every element in the table whereas here arrays are points in the memory. Thank you for all your helpful answers! :D
3

You are correct. You have a pointer to a block of memory, not an actual array.

int getSizeOfPointerArray(int a[]) is the same as: int getSizeOfPointerArray(int* a), so either way you will still be passing a pointer to the first element in your array.

What you are doing is undefined behavior.

There is no portable way to get the size of a dynamic allocation because it depends on each OS.

If you have an actual array, you could do something with templates like:

template <typename T, size_t N>
size_t getSizeInBytes(const T (&array)[N])
{
    return N * sizeof(T);
}

Comments

1

The simplest solution would be to use the vector type in the STL. It has built-in functions which allows you to get the length of the vector. The size is then simply the length times the 'sizeof()' of a single element.

1 Comment

The size of a vector is (probably) sizeof(T*) * 3 the size of the data is also not that simple to talk about (are you talking about the allocated memory or the used memory). It's also unimportant, the number of elements in a vector is what you're usually interested in and that is vec.size().

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.