### Thread: Defining and initialization of array using pointers

1. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2012
Posts
6
Rep Power
0

#### Defining and initialization of array using pointers

Please go through this code :

/*
main()
{

int i, *a;
*a =10;
*(a+1) = 3;
*(a+2) =6;

for (i=0; i<3; i++ )
printf("%d\n", a[i]);
getch();
} */

I think this is one way of defining and initializing a 1D array
or is there any difference in the classic way of initializing the array i.e
int arr[] = {10,3,6};

Also, how can a 2D array be defined and initialized in the similar manner using pointers ??

Thanks...
2. Well given that your 'pointer' method uses an uninitialised pointer, perhaps you should begin by addressing that issue, before trying something complicated like 2D arrays.

Also, initialisation is not the same thing as assignment.

*a = 10;
is assignment,

whereas
char a[] = { 10 };
is initialisation.
3. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2012
Posts
6
Rep Power
0
isn't it right to say that assigning values of same type and size to contagious memory locations ( using pointers ) creates an array ?

if yes, how is it possible to assign values in similar manner to create a 2D array ?
4. Assignment doesn't create anything.

At the very least, you need to begin with
int *a = malloc( 3 * sizeof(int) );
Then you can do
*a = 10;
*(a+1) = 20;
*(a+2) = 30;

The fact that you can also do
a[0] = 10;
a[1] = 20;
a[2] = 30;

doesn't take away the need to allocate the memory in the first place, or magically change the pointer into an array.

Read this since you seem to be confused about the whole pointer/array relationship.

> if yes, how is it possible to assign values in similar manner to create a 2D array ?
It is, but I'm not going to say how until you're OK on just one dimension.
5. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2012
Posts
6
Rep Power
0

may bother u again if I get stuck..
6. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2012
Posts
6
Rep Power
0
read about allocating memory and understood the need to use malloc or calloc ....

a little confusion..
why would this code work ??

/*
main()
{

int i, *a;
*a =10;
*(a+1) = 3;
*(a+2) =6;

for (i=0; i<3; i++ )
printf("%d\n", a[i]);
getch();
} */
7. > why would this code work ??
Pure dumb luck.

- Today, it works.
- Tomorrow, it crashes.
- Next week - where the !\$?" are my OS install disks!?

Not a lot can happen in a user land process; the OS will kill off any process trying to access illegal memory.

But if you were programming a kernel mode driver, or writing code for a bare board, then all bets are off. Pretty much anything can happen, including causing physical damage to hardware (the kind that involves spending money to replace).
8. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2012
Posts
6
Rep Power
0
I tried to dynamically allocate a 2D array :

code:
/*
main()

{
int **arr,x,y,i,j;
x=5;
y=2;
arr = malloc ( x * sizeof(int*));
for (i=0; i<x; i++)
{
*(arr+i) = (int*)malloc(y*sizeof(int));
}
for (i=0; i<x; i++)
{
for (j=0; j<y; j++)
{
printf ("\n%d", &arr[i][j]);
}
}

getch();

} */

Output :

8720136
8720140
8720272
8720276
8720288
8720292
8720304
8720308
8720320
8720324

I see that memory isn't contiguous, why should it be called an array then ?
9. Well arr itself is contiguous, as is each arr[i]
10. Originally Posted by check.wsx
I tried to dynamically allocate a 2D array :
First, use code tags!!!!

Code:
```main()
{
int **arr,x,y,i,j;
x=5;
y=2;
arr = malloc ( x * sizeof(int*));
for (i=0; i<x; i++)
{
*(arr+i) = (int*)malloc(y*sizeof(int));
}
for (i=0; i<x; i++)
{
for (j=0; j<y; j++)
{
printf ("\n%d", &arr[i][j]);
}
}

getch();

}```
If you don't use code tags, then you lose all formatting. That makes your code unreadable and hence we cannot feel bothered to attempt to read it.

Sheesh!

Originally Posted by check.wsx
I see that memory isn't contiguous, why should it be called an array then ?
If you had declare it as a proper 2D array, then you should expect it to be contiguous. What do you find in such a case?

Since you had codged it together out of bits and pieces in the heap, what do you expect?

Each row you had malloc'd out of the heap should be contiguous. Since each row had been malloc'd from wherever, why should you expect those rows to be contiguous to each other?

What do you expect? Do you understand what is happening? Why do you expect what you expect? That is not a rhetorical question!
11. Originally Posted by check.wsx
I see that memory isn't contiguous, why should it be called an array then ?
It is not; it is an array of pointers to arrays. It is not the same as an array in the sense the language defines an array, but can nonetheless be accessed using array notation.

To achieve a contiguous block so that it is equivalent to a built-in array, you would allocate a single contiguous block of size x*y*sizeof(int), then assign arr with pointers into that block.

Also prefer initialisation to separate declaration and assignment, prefer array notation to pointer arithmetic where possible, and strictly %p is the correct format specifier for a pointer not %d:

C Code:
```

#include <stdio.h>
#include <stdlib.h>

int main()
{
int x = 5 ;
int y = 2 ;
int* memblock = malloc( x * y * sizeof(*memblock) ) ;
int** arr = malloc ( x * sizeof(*arr) ) ;
int i, j ;

for( i = 0; i < x; i++ )
{
arr[i] = &memblock[i * y] ;
}

for( i = 0; i < x; i++ )
{
for( j = 0; j < y; j++ )
{
printf( "\n%p", &arr[i][j] ) ;
}
}

return 0 ;
}```
12. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2012
Posts
6
Rep Power
0
Originally Posted by salem

> if yes, how is it possible to assign values in similar manner to create a 2D array ?
It is, but I'm not going to say how until you're OK on just one dimension.
Now that I am Ok wid one dimension, it's time....
wanna try your version as well..
13. OK, here are various ways of allocating, using and freeing 2D arrays.
Code:
```#include <stdio.h>
#include <stdlib.h>

#define ROWS 5
#define COLS 10

// Allocate arrays
// ---------------

// Allocate an array to store all the pointers to the rows,
// then allocate for each row.
int **allocPointerToPointer ( int rows, int cols ) {
int r;
int **result = malloc( rows * sizeof(*result) );
for ( r = 0 ; r < rows ; r++ ) {
result[r] = malloc( cols * sizeof(*result[r]) );
}
return result;
}

// Allocate an array to store all the pointers to the rows,
// then allocate for all the data in a single contiguous block
// Then loop to manually partition the data block for each row
// Use it in the same way as anything allocated with allocPointerToPointer
// but it needs a different free function.
int **allocPointerToPointerContiguous ( int rows, int cols ) {
int **result = malloc(rows*sizeof(*result));
int *data = malloc(rows*cols*sizeof(*data));
int r;
for ( r = 0 ; r < rows ; r++ ) {
// note: the first row is also a pointer to the whole
// block, which is used when it comes to freeing it.
result[r] = data;
data += rows;
}
return result;
}

// Allocate rows of [COLS] arrays
// Use this when the minor dimensions are a compile time constant.
int (*allocPointerToArray(int rows))[COLS] {
int (*result)[COLS] = malloc( rows * sizeof(*result) );
return result;
}

// Free arrays
// -----------
// These just match the previous mallocs.
void freePointerToPointer ( int **p, int rows ) {
int r;
for ( r = 0 ; r < rows ; r++ ) {
free( p[r] );
}
free( p );
}
void freePointerToPointerContiguous ( int **p ) {
free( p[0] );
free( p );
}
void freePointerToArray ( int (*p)[COLS] ) {
free( p );
}

// Initialise contents of arrays
// -----------------------------
// Notice how the loop construct is identical in all cases.
void initPointerToPointer ( int **p, int rows, int cols ) {
int r,c;
for ( r = 0 ; r < rows ; r++ ) {
for ( c = 0 ; c < cols ; c++ ) {
p[r][c] = r * c;
}
}
}
void initPointerToArray ( int (*p)[COLS], int rows ) {
int r,c;
for ( r = 0 ; r < rows ; r++ ) {
for ( c = 0 ; c < COLS ; c++ ) {
p[r][c] = r * c;
}
}
}

// Print contents
// --------------
// Notice how the loop construct is identical in all cases.
// Rather than [r][c], I've used pointer notation instead just for effect
void printPointerToPointer ( int **p, int rows, int cols ) {
int r,c;
int *q;
for ( r = 0 ; r < rows ; r++, p++ ) {
for ( c = 0, q = *p ; c < cols ; c++, q++ ) {
printf("%2d ", *q);
}
printf("\n");
}
printf("\n");
}
void printPointerToArray ( int (*p)[COLS], int rows ) {
int r,c;
int *q;
for ( r = 0 ; r < rows ; r++, p++ ) {
for ( c = 0, q = *p ; c < COLS ; c++, q++ ) {
printf("%2d ", *q);
}
printf("\n");
}
printf("\n");
}

int main(void)
{
int a1[ROWS][COLS];
int (*a2)[COLS] = allocPointerToArray(ROWS);
int **a3 = allocPointerToPointer(ROWS,COLS);
int **a4 = allocPointerToPointerContiguous(ROWS,COLS);

initPointerToArray(a1,ROWS);
initPointerToArray(a2,ROWS);
initPointerToPointer(a3,ROWS,COLS);
initPointerToPointer(a4,ROWS,COLS);

printPointerToArray(a1,ROWS);
printPointerToArray(a2,ROWS);
printPointerToPointer(a3,ROWS,COLS);
printPointerToPointer(a4,ROWS,COLS);

// no need to free a1, it's just an array
freePointerToArray(a2);
freePointerToPointer(a3,ROWS);
freePointerToPointerContiguous(a4);

return 0;
}```