user3753834
user3753834

Reputation: 369

C - Dynamic Memory

I'm learning about dynamic memory at the moment, but my book is not clear about this. Why does the declaration of the dynArray doesn't not have the [ ] brackets which is used for array declaration when not using malloc. Why is the [ ] not needed when declaring, but needed in the loop.

int * dynArray;
dynArray = malloc(sizeof(int)*5);
srand ( time(NULL) );

for(i=0; i<=myInt; i++){
    dynArray[i] = rand()%100;
  }

Upvotes: 2

Views: 183

Answers (3)

This defines an array of a certain size:

int array1[10];

This defines a pointer to integer:

int * array2;

Both definitions allocate some memory. The first one allocates space to hold 10 ints. The second one allocates space to hold a pointer to integer.

When the array1 is used in an expression as an rvalue, it degenerates to a pointer. So using array1 rvalue is equivalent to taking its address: &array1. In an expression, array1 and array2 rvalues are equivalent: they act as pointer-to-int values. The difference is that you can't use array1 as an lvalue: you can't assign to it, and you can't modify it - because it's not a pointer you can write to. You can certainly, of course, modify the values pointed-to by either array1-acting-as-a-pointer, or by array2.

Both definitions above give you uninitialized variables: the contents of array1 are not defined, neither are the contents of array2. So, for example, it'd be an error to dereference the array2 pointer before a value was assigned to it.

You can set array2 to the address of the 10 integer-long area allocated in array1, and both are then equivalent:

int array1[10];
int * array2 = array1;
array1[0] = 1;
array2[0] ++; // Increment the first item of the array
assert(array1[0] == 2);

But while you can certainly make array2 point to the second item in the first array, you can't change where array1 points to:

array2 ++; // Increment the pointer so that it points to the second item of the array
assert(array2 == &array1[1]);

array1 ++; // Triggers a compile-time error diagnostic

The assert, from #include <assert.h>, is simply a way to assert certain facts. If they prove false at runtime, the program will abort. It's also a way to succinctly express, in the C language, that certain things are true at certain points in the program. It's better than writing comments, since the assertion will be checked for you in a debug build, at runtime.

Upvotes: 1

Mike Dunlavey
Mike Dunlavey

Reputation: 40669

The difference is in when its address is known.

For a simple int a[5] array, the compiler knows where it is, so its address is constant (or stack- or struct-relative, which is the same thing).

OTOH int* a means a is just a variable, not a constant, that happens to point to one or more int. The running program can do its own allocation and set a, and it's up to the programmer to know what he/she is doing.

But indexing a[i] works the same in either case. It takes a as the address of the array, then adds to it i times the size of an int, and that's the address of the actual integer.

Upvotes: 1

abasterfield
abasterfield

Reputation: 2292

It is not needed in the loop; pointers can be accessed as arrays and arrays can be accessed as pointers

This is equivalent

for(i=0; i<=myInt; i++){
    *(dynArray+i) = rand()%100;
}

Upvotes: 2

Related Questions