Joao Parente
Joao Parente

Reputation: 453

Confusion between "int array[int]" and "int *array"

int array[100];

int *array;

I am confused about the differences between int array[100] and int *array.

Essentially, when I do int array[100] (100 it's just an example of an int), I just reserved space in memory for 100 ints, but I can do int * array and I didn't specify any type of size for this array, but I can still do array[9999] = 30 and that will still make sense.

So what's the difference between these two?

Upvotes: 6

Views: 8686

Answers (7)

Syed Waris
Syed Waris

Reputation: 1084

Without specifying size in int * array, array[9999] = 30 can cause segmentation fault as it may lead to accessing of inaccessible memory

Basically int * array points to a random location. For accessing the 9999th element the array must point to a location having that much sufficient space. But the statement int * array doesn't explicitly creates any space for that.

Upvotes: 0

chqrlie
chqrlie

Reputation: 145317

int array[100]; defines an array of int.

int *array; defines a pointer to an int. This pointer may point to an int variable or to an element of an array of int, or to nothing at all (NULL), or even to an arbitrary, valid or invalid address in memory, which is the case when it is an uninitialized local variable. It is a tad misleading to call this pointer array, but commonly used when naming a function argument that indeed points to an actual array. The compiler cannot determine the size of the array, if any, from the pointer value.

Here is a topographic metaphor:

  • Think of an array as a street with buildings. It has GPS coordinates (memory address) a name (but not always) and a fixed number of buildings (at a given time, hard to change). The street name together with the building number specifies a precise building. If you specify a number larger than the last number, it is an invalid address.

  • A pointer is a very different thing: think of it as a an address label. It is a small piece of paper that can be used to identify a building. If it is blank (a null pointer), it is useless and if you stick it to a letter and send that, the letter will get lost and discarded (undefined behavior, but it is easy to tell that it is invalid). If you write an invalid address on it, the effect is similar, but might cost much more before failing delivery (undefined behavior and difficult to test for).

  • If a street is razed (if memory was freed), previously written address labels are not modified, but they no longer point the anything useful (undefined behavior if you send the letter, the difficult kind). If a new street is later named with the name on the label, the letter might get delivered, but probably not as intended (undefined behavior again, memory was freed and some other allocated object happens to be at the same memory address).

  • If you pass a building to a function, you would usually not unearth it and truck it, but merely pass its street address (a pointer to the n-th building of the street, &array[n]). If you don't specify a building and just name the street, it means go to the beginning of the street. Similarly, when passing an array to a function is C, the function receives a pointer to the beginning of the array, we say that arrays decays as pointers.

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409482

A pointer is a pointer, it points somewhere else (like the first element of an array). The compiler doesn't have any information about where it might point or the size of the data it might point to.

An array is, well, an array of a number of consecutive elements of the same type. The compiler knows its size, since it's always specified (although sometimes the size is only implicitly specified).

An array can be initialized, but not assigned to. Arrays also often decay to pointers to their first element.

Array decay example:

int array[10];

int *pointer = array;  // Here the symbol array decays to the expression &array[0]

// Now the variable pointer is pointing to the first element of array

Arrays can't naturally be passed to function. When you declare a function argument like int arr[], the compiler will be translating it as int *arr.

All of this information, and more, should be in any good book, tutorial or class.

Upvotes: 8

funnydman
funnydman

Reputation: 11396

Some points that you can find useful to know:

  • Via int arr[N] you specify an array of type int which can store N integers. To get information about how much memory array is taking you can use sizeof operator. Just multiply the number of items in an array by the size of type: N*sizeof(int).
  • Name of the array points to the first element in an array, e.g. *arr is the same as arr[0], also you may wonder why a[5] == 5[a].
  • An uninitialized array of non-static storage duration is filled with indeterminate values.
  • The size of an array may be known at runtime, if you write int arr[] = {1, 2} the size is calculated by a compiler.
  • Accessing an unexisting element can cause undefined behaivor, which means that anything could happen, and in most cases you'll get garbage values.

  • Via int *array you specify a pointer array of type int
  • Unless a value is assigned, a pointer will point to some garbage address by default.
  • If you don't allocate memory at all or not fully allocate it or access unexisting element but try to use a pointer as an array, you'll get undefined behavior as expected.
  • After allocating memory (when the pointer is no longer needed) memory should be freed.

Upvotes: 1

Andrew Henle
Andrew Henle

Reputation: 1

A non-technical explanation:

A pointer's contents refer to an address (which may or may not be valid). An array has an address (which must be valid for the array to exist).

You can think of a pointer as being like an envelope - you can put any address you want on it, but if you want it sent to somewhere in particular, that address has to be correct.

An array is like your house - it exists somewhere, so it has an address. Things properly addressed get sent there.

In short:

A pointer holds an address.

An array has an address.

So

int *array;

creates a pointer of indeterminate value (it can point anywhere!).

When you then have

array[9999] = 30;

you're trying to set the 9999th int value from where array points to the value of 30. But you don't know where array points because you didn't give it an actual value.

And that's undefined behavior.

Upvotes: 3

Amal John
Amal John

Reputation: 59

int array[100] means a variable array which will be able to hold 100 int values this memory will be allocated from the stack. The variablearray will be having the base address of the array and memory will be allocated for the same.

But in the case of int *array since you are declaring this as a local variable, pointer variable array will be having a garbage address. So if you do array[9999] it could cause a segmentation violation since you are trying to access garbage memory location outside your program.

Upvotes: 2

Leo
Leo

Reputation: 751

The difference is when you do int array[100], a memory block of 100 * sizeof(int) is allocated on the stack, but when you do int *array, you need to dynamically allocate memory (with malloc function for example) to use the array variable. Dynamically allocated memory is on the heap, not stack.

Upvotes: 2

Related Questions