开发者

Whats the difference? Pointer to an array vs regular array

I'm familiar with Java and trying to teach myself C/C++. I'm stealing some curriculum from a class that is hosting their materials here. I unfortunately can't ask the teacher since I'm not in the class. My concern is with the section under "dynamically declared arrays":

If you want to be able to alter the size of your array at run time, then declare dynamic arrays. These are done with pointers and the new operator. For the basics on pointers, read the pointers section.

Allocate memory using new, and then you access the array in the same way you would a static array. For example,

int* arrayPtr = new int[10]; for (int i = 0; i < 10; i++) { arrayPtr[i] = i; }

The memory picture is identical to the static array, but you can change the size if you need to. Don't forget you must deallocate the memory before allocating new memory (or you will have a memory leak).

delete [] arrayPtr; // the [] is needed when deleting array pointers arrayPtr = new int[50]; . . .

When you're completely done with the array, you must delete its memory:

delete [] arrayPtr;

Dynamic multi-dimensional arrays are done in a similar manner to Java. You will have pointers to pointers. For an example, see a

My understanding is that an array in C is simply a reference to the memory address of the firs开发者_开发技巧t element in the array.

So, what is the difference between int *pointerArray = new int[10]; and int array[10]; if any?

I've done some tests that seem to indicate that they do the exact same thing. Is the website wrong or did I read that wrong?

#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char** argv) {

    // Initialize the pointer array
    int *pointerArray = new int[10];
    for (int i = 0; i < 10; i++){

        pointerArray[i] = i;
    }

    // Initialize the regular array
    int array[10];
    for (int i = 0; i < 10; i++){

        array[i]= i;
    }

    cout << *(pointerArray + 5) << endl;
    cout << *(array + 5) << endl;

    cout << pointerArray[5] << endl;
    cout << array[5] << endl;

    cout << pointerArray << endl;
    cout << array << endl;

    return 0;
}

Output:

5
5
5
5
0x8f94030
0xbfa6a37c

I've tried to "dynamically re-size" my pointer array as described on the site, but my new (bigger) pointer array ends up filled with 0's which is not very useful.


int array[10]; declares the array size statically, that means it is fixed - which is the only major difference. It also might be allocated to be inside the function's stack frame, i.e. on the program's stack. You do not need to worry about using delete [] on that kind of array, in fact, you might crash the program if you delete it.

When you use operator new, you allocate memory dynamically which could be slower and the memory usually comes from the heap rather than the program's stack (though not always). This is better in most cases, as you are more limited in the stack space than the heap space. However, you must watch out for memory leaks and delete[] your stuff when you don't need it anymore.

As to your array being filled with zeros, what your class material does not say is that you have to do this:

int *arr = new int[20]; // old array
//do magic here and decide that we need a bigger array
int *bigger = new int[50]; // allocate a bigger array
for (int i = 0; i < 20; i++) bigger[i] = arr[i]; // copy the elements from the old array into the new array
delete[] arr;
arr = bigger;

That code extends the array arr by 30 more elements. Note that you must copy the old data into the new array, or else it will not be there (in your case, everything becomes 0).


My understanding is that an array in C is simply a reference to the memory address of the first element in the array.

So, what is the difference between int *pointerArray = new int[10]; and int array[10]; if any?

What you mention is the reason for much confusion in any C/C++ beginner.

In C/C++, an array corresponds to a block of memory sufficiently large to hold all of its elements. This is associated to the [] syntax, like in your example:

int array[10];

One feature of C/C++ is that you can refer to an array by using a pointer to its type. For this reason, you are allowed to write:

int* array_pointer = array;

which is the same as:

int* array_pointer = &array[0];

and this allows to access array elements in the usual way: array_pointer[3], but you cannot treat array as a pointer, like doing pointer arithmetics on it (i.e., array++ miserably fails).

That said, it is also true that you can manage arrays without using the [] syntax at all and just allocate arrays by using malloc and then using them with raw pointers. This makes the "beauty" of C/C++.

Resuming: a distinction must be made between the pointer and the memory that it points to (the actual array):

  1. the [] syntax in declarations (i.e., int array[10];) refers to both aspects at once (it gives you, as to say, a pointer and an array);

  2. when declaring a pointer variable (i.e., int* p;), you just get the pointer;

  3. when evaluating an expression (i.e., int i = p[4];, or array[4];), the [] just means dereferencing a pointer.

Apart from this, the only difference between int *pointerArray = new int[10]; and int array[10]; is that former is allocated dynamically, the latter on the stack.


Dynamically allocated:

int * pointerArray = new int[10]; 

[BTW, this is a pointer to an array of 10 ints, NOT a pointer array]

Statically allocated (possibly on the stack):

int array[10]; 

Otherwise they are the same.


The problem with understanding C/C++ arrays when coming from Java is that C/C++ distinguishes between the array variable and the memory used to store the array contents. Both concepts are important and distinct. In Java, you really just have a reference to an object that is an array.

You also need to understand that C/C++ has two ways of allocating memory. Memory can be allocated on the help or the stack. Java doesn't have this distinction.

In C and C++, an array variable is a pointer to the first element of the array. An array variable can exist on the heap or the stack, and so can the memory that contains its contents. And they can be difference. Your examples are int arrays, so you can consider the array variable to be an int*.

There are two differences between int *pointerArray = new int[10]; and int array[10];:

The first difference is that the memory that contains the contents of the first array is allocated on the heap. The second array is more tricky. If array is a local variable in a function then its contents are allocated on the stack, but if it is a member variable of a class then its contents are allocated wherever the containing object is allocated (heap or stack).

The second difference is that, as you've realised, the first array is dynamic: its size can be determined at run-time. The second array is fixed: the compiler must be able to determine its size at compile time.


First, I'd look for some other place to learn C++. The page you cite is very confusing, and has little to do with the way one actually programs in C++. In C++, most of the time, you'd use std::vector for an array, not the complex solutions proposed on the page you cite. In practice, you never use operator new[] (an array new).

In fact, std::vector is in some ways more like ArrayList than simple arrays in Java; unlike an array in Java, you can simply grow the vector by inserting elements into it, preferrably at the end. And it supports iterators, although C++ iterators are considerably different than Java iterators. On the other hand, you can access it using the [] operator, like a normal array.

The arrays described on the page you cite are usually called C style arrays. In C++, their use is mostly limited to objects with static lifetime, although they do occasionally appear in classes. In any case, they are never allocated dynamically.


The main difference is that some operations that are allowed on pointers are not allowed on arrays.


On the one hand:

int ar[10];

is using memory allocated on the stack. You can think of it also locally available and while it is possible to pass a pointer / reference to otehr functions, the memory will be freed as soon as it goes out of scope (in your example at the end of the main method but that's usually not the case).

On the other hand:

int ar* = new int[10];

allocates the memory for the array on the heap. It is available until your whole program exits or it is deleted using

delete[] ar;

note, that for delete you need the "[]" if and only if the corresponding new has had them, too.


There is a difference but not in the area that you point to. *pointerArray will point to the beginning of a block of memory of size 10 bytes. So will array. The only difference will be where it is stored in memory. pointerArray is dynamically assigned memory (at run-time) and hence will go on the heap, while array[10] will be allocated at compile-time and will go to the stack.


It is true that you can get most of array functionality by using a pointer to its first element. But compiler knows that a static array is composed of several elements and the most notable difference is the result of the sizeof operator.

sizeof(pointerArray) = sizeof int*

sizeof(array) = 10 * sizeof int

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜