C : Passing bi-dimensional array of pointers as argument - c

I'm using a 2d-Array of pointers, each pointer points to a linked list of products.
I want to build a function that list all the products in all the lists.
This is my structure:
typedef struct object product, *pprod;
struct object{
int type;
int quantity;
pprod next;
};
This is how I'm defining the array (it has to be dynamic):
n=4;
m=3;
pprod (*t)[m] = malloc(n * sizeof *t);
list_all(t,n,m);
This is the function to show all the products:
void list_all(pprod** t , int size_n , int size_m) {
int i,j;
for(i=0;i<size_n;i++){
printf("--- Corridor ---: %d\n", i);
for(j=0;j<size_m;j++){
printf("--- Shelf ---: %d\n",j);
printf("product:%d quantity:%d",t[i][j]->type,t[i][j]->quantity);
}
}
}
I'm having troubles passing the array as a parameter. Can you help me find the problem?
Thanks for the help.

Well, first the creation of the array is wrong. You are just assigning one (single) vector of size 4 to the m+1 th element (the t vector, unless you do it elsewhere, points to random-land).
n=4;
m=3;
product **t, *newitem;
t= (product **)calloc(n, sizeof(product *)); // array of n pointers (corridor)
for (int i= 0; i<n; i++) {
t[i]= (product *)calloc(m, sizeof(product)) // array of m prod structs (m shelfs per corridor)
}
// access some array members (t[n][m] max t[0-2][0-3])
t[0][0].type= 0;
t[0][0].quantity= 0;
t[0][1].type= 1;
t[0][1].quantity= 11;
...
t[1][2].type= 12;
t[1][2].quantity= 1212;
....
t[2][3].type= 23;
t[2][3].quantity= 2323;
// more products could be linked to the existing ones
newitem= calloc(1, sizeof product);
newitem->type= 231;
newitem->quantity= 231231;
t[2][3].next= newitem;
// now list them via below function
list_all(t,n,m);
....
void list_all(product **t , int size_n , int size_m)
{
int i,j;
product *p;
for(i=0;i<size_n;i++){
printf("--- Corridor ---: %d\n", i);
for(j=0;j<size_m;j++){
printf("--- Shelf ---: %d\n",j);
p= &t[i][j];
do {
printf("product:%d quantity:%d", p->type, p->quantity);
p= p->next;
} (while p!=NULL);
}
}
}
See also my comment at Etienne's answer for more details.

From your problem description you want to represent i corridors * j shelfs * k products, where each product has a quantity and a type.
In your question you said you want to use a 2D array of pointers but your function list_all takes a 3D array as first argument (t is of type object***). Furthermore your structure object is meant to be a linked list node since it has a next member, but you use it like an array, for example with t[i][j]->quantity, which can not work and attempts to access unallocated memory.
To help reducing this kind of confusion name your variable more explicitly and avoid one letter variable names (n,m,t in your problem) except for loop iterators. Your program will be easier to read and those problems will appear more easily.
Here is a working solution to your problem using a 3D array:
#include <stdio.h>
#include <stdlib.h>
typedef struct object prod;
struct object {
int type;
int quantity;
};
void list_all(prod ***shop, int nb_corridors , int nb_shelfs, int nb_prods)
{
int i,j,k;
for (i = 0; i < nb_corridors; i++) {
printf ("--- Corridor ---: %d\n", i);
for (j = 0; j < nb_shelfs; j++) {
printf ("--- Shelf ---: %d\n", j);
for (k = 0; k < nb_prods; k++) {
printf ("--- Product ---: %d\n", k);
printf ("type:%d quantity:%d\n",
shop[i][j][k].type, shop[i][j][k].quantity);
}
}
}
}
int main(void)
{
int nb_corridors = 4;
int nb_shelfs = 5;
int nb_prods = 3;
prod ***shop;
// array of n pointers (corridor)
shop = malloc(nb_corridors * sizeof(*shop));
printf("sizeof(*shop)=%ld\n", sizeof(*shop));
int i, j;
for (i = 0; i < nb_corridors; i++) {
// nb_shelfs shelfs per corridor)
shop[i] = malloc(nb_shelfs * sizeof(*shop[i]));
printf("sizeof(*shop[i])=%ld\n", sizeof(*shop[i]));
for(j = 0; j < nb_shelfs; j++) {
shop[i][j] = malloc(nb_prods * sizeof(*shop[i][j]));
printf("sizeof(*shop[i][j])=%ld\n", sizeof(*shop[i][j]));
}
}
//initialize with dummy values
int k;
for(i = 0; i < nb_corridors; i++) {
for(j = 0; j < nb_shelfs; j++) {
for(k = 0; k < nb_prods; k++) {
shop[i][j][k].type = k;
shop[i][j][k].quantity;
}
}
}
list_all(shop, nb_corridors, nb_shelfs, nb_prods);
return 0;
}

pprod is already a pointer, I believe the problem is how you pass the parameters to the function.
try changing to this function prototype:
t is already a pointer to a pointer and you aren't changing it anyhow..
void list_all(pprod* t , int size_n , int size_m) {

Related

expected ‘int **’ but argument is of type ‘int (*)[3]’

I just started to tinker with pointers in multidimensional arrays and was trying to pass and array into a void function. The compilator just threw an error. I need the array to be passed exactly as a pointer to maybe change it then by reference.
#include <stdio.h>
#include <stdlib.h>
void Func(int** matrix, int sizeFirst, int sizeSecond)
{
for (int i = 0; i < sizeFirst; i++)
{
for (int j = 0; j < sizeSecond; j++)
{
printf("%d\n", matrix[i][j]);
}
}
}
int main()
{
int array[2][3] = {
{5,8,2},
{1,3,6}
};
int sizeMain = sizeof(array)/sizeof(array[0]);
int sizeInner = sizeof(array[0])/sizeof(array[0][0]);
Func(array, sizeMain, sizeInner);
return 0;
}
2D array is not pointer to pointer. Your code is invalid as Func does not know how many columns every row has. Also, use the correct type for sizes & indexes
void Func(size_t sizeFirst, size_t sizeSecond, int (*matrix)[sizeSecond])
{
for (int i = 0; i < sizeFirst; i++)
{
for (int j = 0; j < sizeSecond; j++)
{
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
int main()
{
int array[2][3] = {
{5,8,2},
{1,3,6}
};
size_t sizeMain = sizeof(array)/sizeof(array[0]);
size_t sizeInner = sizeof(array[0])/sizeof(array[0][0]);
Func(sizeMain, sizeInner, array);
return 0;
}
https://godbolt.org/z/Ejfrdd3nK
With pointers to VLAs, you can preserve all of the dimensions in the type of the argument and then let C do the multidimensional scaling for you.
In older versions of C you need to calculate the spot manually, remembering that
the first dimension from the right moves by 1 (scaled by sizeof(type), which C does for you), the second by first dimension from the right,
the third by first dimension from the right multiplied by second dimension from the right and so on.
It's sort of like digits in numbers (units, tens, hundreds, ...) except that the next scaling is the previous scaling multiplied by the previous dimension rather than by a constant radix.
(You could let C convert groups of decimal digits to decimal numbers by letting it subtract some &decdigits[a][b][c] and &decdigits[0][0][0] where decdigits is some decdigits[10][10][10], i.e.:
char decdigits[10][10][10]; printf("%d\n", (int)(&decdigits[1][2][3] - &decdigits[0][0][0])) /*prints 123*/;)
#include <stdio.h>
void Func( int sizeFirst, int sizeSecond, int (*matrix)[sizeFirst][sizeSecond])
{
for (int i = 0; i < sizeof((*matrix))/sizeof((*matrix)[0]) ; i++)
{
for (int j = 0; j < sizeof((*matrix)[0])/sizeof((*matrix)[0][0]) ; j++)
{
printf("%d ", (*matrix)[i][j]);
}
puts("");
}
}
void Func_89( int sizeFirst, int sizeSecond, int *matrix)
{
for (int i = 0; i < sizeFirst; i++)
{
for (int j = 0; j < sizeSecond; j++)
{
printf("%d ", matrix[i*sizeSecond + j]);
}
puts("");
}
}
int main()
{
int array[2][3] = {
{5,8,2},
{1,3,6}
};
int sizeMain = sizeof(array)/sizeof(array[0]);
int sizeInner = sizeof(array[0])/sizeof(array[0][0]);
Func(sizeMain, sizeInner,&array );
puts("===");
Func_89(sizeMain, sizeInner,&array[0][0] );
//char decdigits[10][10][10]; printf("%d\n", (int)(&decdigits[1][2][3] - &decdigits[0][0][0])); //123
return 0;
}
First of you have to understand what int ** represent, it represents pointer to integer pointer, here's an example:
int a = 10;
int *p = &a; // 'p' points to 'a`
int **pp = &p; // 'pp' points to 'p' (pointer to integer)
So because of this, you can't use int ** for an integer array. Now that's out of the way, let's see what can you do instead (solution)
You can simply add a pointer to an integer array in a function definition like this
void Func(int *matrix[], int rows, int cols)
Or you can simply do
void Func(int matrix[rows][cols])
Note: Array of strings or 2D character array (char array[][]) can be represented as char**

Why do I get a segmentation fault by declaring a 2d array in c?

I am new to threads and I have a program that uses threads to find the minimum number out of a 2d array and later on, it finds the distance that the other elements of the array have from the minimum number and stores them in another array.
The user should enter the size of the array and the number of threads he wants to use.
I tried the program below for 1d array and it worked just fine. When I converted it to work for a 2d array it started crashing and throwing a segmentation fault. I, however, cannot find which part of the 2d declaration is wrong.
Any help is really appreciated.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <pthread.h>
struct Parameters
{
// input
int s,p; //n is size of array, p is number of threads
int** array; //array with elements
int start;
int end;
// output
int smallest;
int pos; //position if minimum
int** B; //array that holds the distances
};
void* min(void* args)
{
struct Parameters* p = (struct Parameters*)args;
int **array = p->array;
int **B1 = p->B;
int start = p->start;
int end = p->end;
int smallest = array[start][start];
int pos = p->pos;
int distance;
//find the smallest
for (int i = start; i < end; i++)
{
for(int j = start; j < end; j++)
{
if (array[i][j] < smallest)
{
smallest = array[i][j];
pos = i;
}
}
}
//find the distances
for(int i = 0; i < ((struct Parameters*)args) -> s; i++)
{
for(int j = 0; j < ((struct Parameters*)args) -> s; j++)
{
distance = abs(pos - i);
B1[i][j] = distance;
}
}
params->smallest = smallest;
params->B = B1;
return NULL;
}
int main()
{
int smallest,pos;
int s,p;
struct Parameters *ptr = (struct Parameters *)malloc(sizeof(struct Parameters));
if(ptr == NULL)
{
printf("Not enough. Try again \n");
exit(0);
}
printf("Type s\n");
scanf("%d",&(ptr->s));
printf("Type p\n");
scanf("%d", &(ptr->p));
// declare an array of threads and associated parameter instances
pthread_t threads[(ptr->p)];
struct Parameters thread_parameters[(ptr->p)] ;
int arr[ptr->s][ptr->s];
int B2[ptr->s][ptr->s];
// intialize the array
for(int i=0; i< ptr->s; i++)
{
for(int j=0; j< ptr->s; j++)
{
printf("Type a \n");
scanf("%d",&arr[i][j]);
}
}
// smallest needs to be set to something
smallest = arr[0][0];
// start all the threads
for (int i = 0; i < ptr->p; i++)
{
memcpy(arr, thread_parameters[i].array, sizeof(arr));
thread_parameters[i].s = ptr->s;
memcpy(Bb, thread_parameters[i].B, sizeof(B2));
thread_parameters[i].start = i * (ptr->s / ptr->p);
thread_parameters[i].end = (i+1) * (ptr->s / ptr->p);
pthread_create(&threads[i], NULL, min, &thread_parameters[i]);
}
// wait for all the threads to complete
for (int i = 0; i < ptr->p; i++)
{
pthread_join(threads[i], NULL);
}
// Now aggregate the "smallest" and "largest" results from all thread runs
for (int i = 0; i < ptr->p; i++)
{
if (thread_parameters[i].smallest < smallest)
{
smallest = thread_parameters[i].smallest;
}
}
printf("Smallest is %d\n", smallest);
thread_parameters[ptr->p].B[ptr->s][ptr->s];
for (int i = 0; i < 1; i++)
{
for(int j = 0; j < ptr->s;j++)
{
for(int k = 0; k < ptr->s; k++)
{
printf("Element %d is %d away from min\n",j,thread_parameters[i].B[j][k]);
}
}
}
return 0;
}
Thank you!!
The issue with your code might also come from :
memcpy(arr, thread_parameters[i].array, sizeof(arr));
...
memcpy(Bb, thread_parameters[i].B, sizeof(B2));
as thread_parameters[i].array and thread_parameters[i].B are not allocated, if you are only reading the array it might b fine to only pass them by address
thread_parameters[i].array = arr
but for thread_parameters[i].B you would need to allocate the arrays and perform a deep copy (memcpy would not work)
The below text does not answer the question but does provide some insight on VLA usage
One reason for causing the segmentation with a declaration of a Variable Length Array is that the value is to large to allocate the array on the stack (some compiler choose this option, this choice might have performance reason).
The is not much option to recover cleanly from failure to allocate memory on the stack as there is little way to clean up stack memory during runtime within the same stack context.
You can mitigate the issue by allocating your 2D arrays on the heap instead, some of the strategies are available here(thanks #Lundin) and here.
int** alloc_2d_int_array(size_t rows, size_t cols) {
int **result = malloc(rows * sizeof(int *));
if(result == NULL) {
// could not allocate more memory
return NULL;
}
size_t row_size = cols * sizeof(int);
for(int i=0; i < rows; ++i) {
result[i] = malloc(row_size);
if(result[i] == NULL) {
// could not allocate more memory
// cleanup
return NULL;
}
}
return result;
}
the above implementation have not been tested, but does compile, there are still risk of integer overflow.
Then use the above define function as following:
int **arr = alloc_2d_int_array(ptr->s, ptr->s);
int **B2 = alloc_2d_int_array(ptr->s, ptr->s);
easier implementation (see here(thanks #Lundin))
int **arr = malloc(sizeof(int[ptr->s][ptr->s]);
int **B2 = malloc(sizeof(int[ptr->s][ptr->s]);

C - address of matrix as an argument in function

I have this header:
#define SIZE 4
typedef float matrix[SIZE][SIZE];
typedef struct {
char *name;
matrix *mat;
} matRec;
void printMat(matrix *);
void read_mat(matrix , float []);
declaration in the main:
matrix m[6];
matRec mats[6] = {
{"MAT_A", &m[0]},
{"MAT_B", &m[1]},
{"MAT_C", &m[2]},
{"MAT_D", &m[3]},
{"MAT_E", &m[4]},
{"MAT_F", &m[5]}
};
struct {
char *name;
void (*func)();
} cmd[] = {
{"read_mat", read_mat},
{"not_valid", NULL}
};
this is also part of my main:
(*(cmd[func].func))(&mats[matrixx].mat, num);
printMat(mats[matrixx].mat);
my printMat function in the main:
void printMat(matrix *matrx) {
int i,j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
printf("%7f ", matrx[i][j]);
}
printf("\n");
}
printf("\n");
}
and the read_mat function (in another file):
void read_mat(matrix matrx, float num[]) {
int i, j, count = 0;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
matrx[i][j] = num[count];
count++;
}
}
}
My purpose is to send an address of my matrix from array: mats, with array of float numbers, insert them, and print the matrix with another function. I have difficulties in sending the address. The read_mat function does "work", but with a copy of matrix(in the scope of the function), then obviously prints matrix with only zeros. I don't understand how to write the right types of arguments with pointers in declaration of function. Any other combination of * gives error. THANKS
I guess few of the type information would help you. Here by saying this
matrix m[6];
You are basically declaring
float m[6][SIZE][SIZE];
And then type of m[0] is nothing but float [SIZE][SIZE] or matrix.
So when I pass it's address to a function it would be
somefun(&m[0]);
You would declare and use it like this
..somefun(matrix *t){
for(int i = 0; i< SIZE; i++)
for(int j =0 ; j< SIZE; j++)
printf("%lf",(*t)[i][j]);
..
}

2D arrays using arrays of pointers or pointers to pointers in C?

I'm writing a C for which I need to create a 2D array. I've found a solution to my problem using double pointers (pointers to pointers) in the following way:
#include <stdio.h>
#include <stdlib.h>
int d = 3;
#define DIM_MAX 9
void changeArray(int d, int *array[d]);
int main()
{
//alocate array of 'd' colummns and 'd' row using malloc using array of pointers
int **array = malloc(d*sizeof(int *));
for(int count = 0; count < d; count++)
{
array[count] = malloc(d*sizeof(int *));
}
/* Call changeArray function */
changeArray(d, array);
for(int i = 0; i < d; i++)
{
for(int j = 0; j < d; j++)
{
printf("%d ", array[i][j]);
}
printf("\n");
}
for(int count = 0; count < d; count++)
{
free(array[count]);
}
return 0;
}
void changeArray(int n, int *array[d])
{
for(int i =0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
array[i][j] = i*j;
}
}
return;
}
The code above works pretty well (it seems), but I've read in the web that using pointer to pointer is not the correct way to create 2D arrays. So I've come up with the following code, which also works:
#include <stdio.h>
#include <stdlib.h>
#define DIM_MAX 9
int d = 3;
void changeArray(int d, int *array[d]);
int main()
{
//alocate array of 'd' colummns and 'd' row using malloc using array of pointers
int *array[DIM_MAX] = {0};
for(int count = 0; count < d; count++)
{
array[count] = (int *)malloc(d*sizeof(int *));
}
/* Call changeArray function */
changeArray(d, array);
for(int i = 0; i < d; i++)
{
for(int j = 0; j < d; j++)
{
printf("%d ", array[i][j]);
}
printf("\n");
}
for(int count = 0; count < d; count++)
{
free(array[count]);
}
return 0;
}
void changeArray(int n, int *array[d])
{
for(int i =0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
array[i][j] = i*j;
}
}
return;
}
What is the difference in using any of the two ways above to write this code?
[Not an answer, but an alternative approach to achieve the desired result, namely defining a user-defined 2D array.]
Assuming the compiler in use supports VLAs you could do this:
#include <stddef.h> /* for size_t */
void init_a(size_t x, size_t y, int a[x][y]); /* Order matters here!
1st give the dimensions, then the array. */
{
for (size_t i = 0; i < x; ++i)
{
for (size_t j = 0; j < y; ++j)
{
a[i][j] = (int) (i * j); /* or whatever values you need ... */
}
}
}
int main(void)
{
size_t x, y;
/* Read in x and y from where ever ... */
{
int a[x][y]; /* Define array of user specified size. */
init_a(x, y, a); /* "Initialise" the array's elements. */
...
}
}
It is actually pretty simple. All you have to do is this:
int i[][];
You are overthinking it. Same as a normal array, but has two indexes.
Let's say you want to create a "table" of 4 x 4. You will need to malloc space for 4 pointers, first. Each of those index points will contain a pointer which references the location in memory where your [sub] array begins (in this case, let's say the first pointer points to the location in memory where your first of four arrays is). Now this array needs to be malloc for 4 "spaces" (in this case, let's assume of type INT). (so array[0] = the first array) If you wanted to set the values 1, 2, 3, 4 within that array, you'd be specifying array[0][0], array[0][1], array[0][2], array[0][3]. This would then be repeated for the other 3 arrays that create this table.
Hope this helps!

Pass static two dimensional struct array to function by reference

I try to pass a static two dimensional struct as a reference to a function.
But I don't know how to get that done in correct way.
From my understanding, I pass a pointer to the first element of struct test to initfield(). C does know the size of the struct test so I can jump to the specific requested locations of the data. I just don't know how to adress the required data.
Here's my code that hopefully describes what I am looking for.
struct test{
int i;
double d;
};
void initfield(struct test *a, int structsize)
{
int i, j;
for (i = 0; i < structsize; i++)
{
for (j = 0; j < structsize; j++)
{
a[i][j]->i = 1;
a[i][j]->d = 1.0;
}
}
}
int main(void)
{
int i, j;
struct test field[8][8];
initfield(field, 8);
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
printf("test[%i][%i].i = %i", i, j, test.i);
printf("test[%i][%i].d = %i", i, j, test.d);
}
}
return 0;
}
Update :
I've replaced both printf's with the following :
printf("test[%i][%i].i = %i", i, j, field[i][j].i);
printf("test[%i][%i].d = %lf", i, j, field[i][j].d);
However, I still encounter errors with initfield.
The problem, is actually, in your initfield() code,
void initfield(struct test *a, int structsize)
a is of type struct test *, and later, you're doing
a[i][j]->i = 1;
which expects a to be struct test **
That said,
for (j = 0; j < 8; j++)
{
printf("test[%i][%i].i = %i", i, j, test.i);
printf("test[%i][%i].d = %i", i, j, test.d);
}
is completely wrong. Neither is there any variable called test, nor you can access a 2-D array using structVar.membervar format. Moreover, you are using %d to print a double, which in turn invokes undefined behaviour.
Solution: You can make use of array properties and pointer arithmetic to achieve what you want.
You have to change the loop inside the initfield() code, like
for (i = 0; i < structsize; i++)
{
for (j = 0; j < structsize; j++)
{
((a+(i*structsize))+j)->i = 7; //I changed the value to store, just like that
((a+(i*structsize))+j)->d = 2.0; //I changed the value to store, just like that
}
}
and, in main(), use %f to print the values.
A Live variant
First, structsize is not a good identifier name. It's not the size of the struct, it's the size of one dimension of the array. I'd implement it with parameters x and y, or width and heigth, or any better names for the two dimensions.
field is also a bad name. A field is often used to call a member of a struct. It is very confusing to use the identifier field to call an array of array of structs.
Then to your problem: field is an array of array of structs. In function parameter, this is equivalent to a pointer to a pointer.
The first parameter of initfield should be of type struct test **. Then later in the function, you dereference twice with your [] operators:
a is of type struct test **
a[i] is of type struct test *
a[i][j] is of type struct test
To access the fields of a[i][j], you need the . operator since its a struct test: a[i][j].d. The operator -> would work if a[i][j] was of type struct test *, but it isn't.
In this case it doesn't matter: as other have said, you can't access the second dimension of the array without explicitly calculating with the help of the size of the first dimension. a[i][j] does not work, you need some kind of pointer arithmetic: struct test *p = a + i * structsize + j and use p->i and p->d.
In the main function however, the dimensions of field are know, so field[i][j].d works.
You're assuming C can figure out that a inside refers to a square array with side length structsize, although you clearly say that a has type "pointer to struct test", which is not the same.
You need to do the indexing manually, inside the function:
static void initfield(struct test *a00, size_t sidelength)
{
for(size_t i = 0; i < sidelength; ++i)
{
for(size_t j = 0; j < sidelength; ++j)
{
struct test *aij = a00 + i * sidelength + j;
aij->i = 1;
aij->j = 1.0;
}
}
}
I didn't test the above, but something like that should work. It basically just uses simple pointer arithmetic to compute the address of the 2D array element at (i, j) given the address of the one at (0, 0).
It works fine i din't thought about doing calculation the adresses myself.
Thanks very much!
Here's my final adapted code which just works perfectly!
struct test{
int i;
double d;
};
void initfield(struct test *a00, int structsize)
{
int i, j;
for (i = 0; i < structsize; i++)
{
for (j = 0; j < structsize; j++)
{
struct test *acurrent = a00 + i * structsize + j;
acurrent->i = 1;
acurrent->d = 1.0;
}
}
}
int main(void)
{
int i, j;
struct test field[8][8];
initfield(&field[0][0], 8);
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
printf("test[%i][%i].i = %i\n", i, j, field[i][j].i);
printf("test[%i][%i].d = %lf\n", i, j, field[i][j].d);
}
}
return 0;
}
Best way to do this:
void initfield(size_t x, size_t y, struct test a[x][y]);
Be aware though, C is strange, the above is still a pointer, equivalent to struct test*. If you wish to have a true array pointer type, you'd have to do:
void initfield(size_t x, size_t y, struct test a[x][y])
{
struct test (*ptr)[x][y] = (void*)a;
or preferably:
struct test (*ptr)[y] = *a;
ptr[i][j] = something; // use the array pointer with sane syntax

Resources