# Thread: What is the difference between types: int **n, *n[3], (*n)[3].

1. ## What is the difference between types: int **n, *n[3], (*n)[3].

And how can I use malloc and calloc to dynamically allocate memory to them?

2. You're looking at declarations of a pointer to a pointer, of an array of pointers, and of a pointer to an array, respectively.

As for how to dynamically allocate memory for them: first, you need to ask yourself what you're trying to allocate, e.g., are you trying to allocate space for a dynamic 1D array, a dynamic rectangular 2D array, a dynamic jagged 2D array, etc?

3. int **n
You can synthesise any n[x][y] kind of array, and each y can be different (ragged)
Code:
```n = malloc(x*sizeof(*n));
for(i = 0 ; i < x ; i++)
n[i] = malloc(y*sizeof(*n[i]));```
int *n[3]
You can synthesis any n[3][y] kind of array, and each y can be different (ragged)
Code:
```for(i = 0 ; i < 3 ; i++)
n[i] = malloc(y*sizeof(*n[i]));```
int (*n)[3]
You can synthesis any n[x][3] kind of array
Code:
`n = malloc(x*sizeof(*n));`

4. Assuming they are all supposed to be transformed into some kind of 2-d array, here are some possibilities.
Code:
```#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// For allocation of triangular array data block.
int sum1ToN(int n) { return (n * (n + 1)) / 2; }

// Allocator that exits on failure.
void *alloc(size_t size) {
void *p = calloc(1, size);
if (!p) {
perror("alloc");
exit(EXIT_FAILURE);
}
return p;
}

// Macro so allocator can be called ALLOC(count, type)
#define ALLOC(count, type) alloc((count) * sizeof(type))

int main() {
srand(time(0)); // Jagged array row lengths are random.

// Rectangular 2-d array
{
const int Rows = 5, Cols = 10;

int **a = ALLOC(Rows, *a);               // array of row pointers
a[0] = ALLOC(Rows * Cols, **a);          // data block
for (int row = 1; row < Rows; ++row)     // set row pointers to
a[row] = a[row - 1] + Cols;          // point into data block

for (int row = 0; row < Rows; ++row) {
for (int col = 0; col < Cols; ++col)
printf("%d ", a[row][col]);
putchar('\n');
}
putchar('\n');

free(a[0]);
free(a);
}

// Triangular array (short row first)
{
const int Size = 8;

int **a = ALLOC(Size, *a);
a[0] = ALLOC(sum1ToN(Size), **a);
for (int row = 1; row < Size; ++row)
a[row] = a[row - 1] + row;

for (int row = 0; row < Size; ++row) {
for (int col = 0; col < row + 1; ++col)
printf("%d ", a[row][col]);
putchar('\n');
}
putchar('\n');
free(a[0]);
free(a);
}

// Triangular array (long row first)
{
const int Size = 8;

int **a = ALLOC(Size, *a);
a[0] = ALLOC(sum1ToN(Size), **a);
for (int row = 1; row < Size; ++row)
a[row] = a[row - 1] + (Size + 1) - row;

for (int row = 0; row < Size; ++row) {
for (int col = 0; col < Size - row; ++col)
printf("%d ", a[row][col]);
putchar('\n');
}
putchar('\n');
free(a[0]);
free(a);
}

// Jagged 2-d array
{
const int Rows = 5;

int **a = ALLOC(Rows, *a);
for (int row = 0; row < Rows; ++row) {
// assigning random number of columns to each row
int size = rand() % 9 + 1; // 1 to 9
a[row] = ALLOC(size + 1, **a); // + 1 for a sentinel
a[row][size] = -1; // set sentinel (assuming -1 is unused value)
}
// Instead of a sentinel you could store the size in the first element.

for (int row = 0; row < Rows; ++row) {
for (int col = 0; a[row][col] != -1; ++col)
printf("%d ", a[row][col]);
putchar('\n');
}
putchar('\n');

for (int row = 0; row < Rows; ++row)
free(a[row]);
free(a);
}

// If the jagged row sizes are unchanging you could still allocate
// the data in a single block and set the row pointers to point into it.
// In that case you could also use the start pointer of the next
// row to detect the end of the current row. This makes the last row
// a problem, but you could allocate one extra row pointer.

// Jagged 2-d array; single data block
{
const int Rows = 5;

// Generate random row sizes.
int *sizes = ALLOC(Rows, *sizes);
int total_size = 0;
for (int row = 0; row < Rows; ++row)
total_size += sizes[row] = rand() % 9 + 1; // 1 to 9

// Allocate 1 extra row pointer for a "one-past-the-end" address.
int **a = ALLOC(Rows + 1, *a);
a[0] = ALLOC(total_size, **a);
for (int row = 1; row < Rows + 1; ++row)
a[row] = a[row - 1] + sizes[row - 1];

free(sizes);

for (int row = 0; row < Rows; ++row) {
for (int col = 0; &a[row][col] != &a[row+1][0]; ++col)
printf("%d ", a[row][col]);
putchar('\n');
}
putchar('\n');

free(a[0]);
free(a);
}

// Array of 3 pointers-to-int

// This is basically a preallocated set of 3 "row pointers", so we need to
// allocate the data block (e.g.) and point the row pointers into it,
// or allocate each row separately.
{
const int Rows = 3, Cols = 5;
int *a[Rows];

a[0] = ALLOC(Rows * Cols, *a);
for (int row = 1; row < Rows; ++row)
a[row] = a[row - 1] + Cols;

for (int row = 0; row < Rows; ++row) {
for (int col = 0; col < Cols; ++col)
printf("%d ", a[row][col]);
putchar('\n');
}
putchar('\n');

free(a[0]);
}

// Pointer to array of 3 ints.

// Points to one or more array(s) of 3 ints.
// Each allocated element allocates a row of 3 data columns.
{
const int Rows = 5, Cols = 3;
int (*a)[Cols];

a = ALLOC(Rows, *a);

for (int row = 0; row < Rows; ++row) {
for (int col = 0; col < Cols; ++col)
printf("%d ", a[row][col]);
putchar('\n');
}
putchar('\n');

free(a);
}

return 0;
}```
Code:
```0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

0
0 0
0 0 0
0 0 0 0
0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0
0 0 0 0
0 0 0
0 0
0

0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0
0 0 0 0 0 0 0

0 0 0 0
0 0 0 0
0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0

0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

0 0 0
0 0 0
0 0 0
0 0 0
0 0 0```

5. Thank you!!

Popular pages Recent additions