If you have to work with double pointers through a function (passing a double pointer as parameter aka triple pointer!), here are some codes I wrote a very long time ago to address specifically that problem.
I hope it can be useful to those having trouble with double/triple pointers. Note that I'm working with integers, but the idea also applies to other types.
Double pointer via function (triple pointer)
I think the important things to note are the following syntaxes
- how to declare
int ***coco_a
- how to allocate1
*coco_a = (int **) calloc(ROW, sizeof(int *));
- how to allocate2
(*coco_a)[i] = (int *) calloc(COL, sizeof(int));
- how to populate
scanf("%d", &(*coco_a)[i][j]);
It took me a long time to realize that &(*coco_a)
works and &*coco_a
(or coco_a
) does not work!
Here's the test code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROW 2
#define COL 2
void aloca(int ***coco_a)
{
*coco_a = (int **) calloc(ROW, sizeof(int *));
int i;
for(i=0; i<ROW; ++i) {
(*coco_a)[i] = (int *) calloc(COL, sizeof(int));
int j;
for(j=0; j<COL; ++j) {
scanf("%d", &(*coco_a)[i][j]);
}
}
}
int main(int argc, char *argv[]) {
int **coco_m;
aloca(&coco_m);
int i, j;
/*for(i=0; i<ROW; ++i)
for(j=0; j<COL; ++j)
scanf("%d", &coco_m[i][j]);*/
for(i=0; i<ROW; ++i)
for(j=0; j<COL; ++j)
printf("coco[%d][%d] = %d\n", i, j, coco_m[i][j]);
return 0;
}
The following illustrates the usage of contiguous versus non-contiguous double pointers.
Contiguous versus non-contiguous allocation
#include <stdlib.h>
#include <stdio.h>
#define ROW 2
#define COL 3
int main(void)
{
int i, j, val = 0;
/* Allocation and assignment */
int **doub_pointer = (int **) calloc(ROW, sizeof(int *));
printf("\ndoub_pointer = %d\n", doub_pointer);
for(i=0; i < ROW; ++i) {
doub_pointer[i] = (int *) calloc(COL, sizeof(int));
if(i == 0) printf("*doub_pointer = %d\n", *doub_pointer);
for(j=0; j < COL; ++j) {
doub_pointer[i][j] = val++;
printf("&doub_pointer[%d][%d] = %d\n", i, j, &doub_pointer[i][j]);
}
}
/* Printing */
for(i=0; i < ROW; ++i) {
for(j=0; j < COL; ++j){
printf("doub_pointer[%d][%d] = %d\n", i, j, doub_pointer[i][j]);
}
}
printf("sizeof(doub_pointer) = %d\n", sizeof(doub_pointer)/sizeof(int));
printf("sizeof(doub_pointer[0]) = %d\n", sizeof(doub_pointer[0])/sizeof(int));
/* Freeing */
for(i=0; i < ROW; ++i) free(doub_pointer[i]);
free(doub_pointer);
/*******************************************************************/
val = 0;
/* Allocation and assignment */
int (*pointer)[COL] = (int (*)[COL]) calloc(ROW, sizeof(int [COL]));
printf("\npointer = %d\n", pointer);
for(i=0; i < ROW; ++i) {
for(j=0; j < COL; ++j){
pointer[i][j] = val++;
printf("&pointer[%d][%d] = %d\n", i, j, &pointer[i][j]);
}
}
/* Printing */
for(i=0; i < ROW; ++i) {
for(j=0; j < COL; ++j){
printf("pointer[%d][%d] = %d\n", i, j, pointer[i][j]);
}
}
printf("sizeof(pointer) = %d\n", sizeof(pointer)/sizeof(int));
printf("sizeof(pointer[0]) = %d\n", sizeof(pointer[0])/sizeof(int));
/* Freeing */
free(pointer);
/*******************************************************************/
int true_2D[ROW][COL];
printf("\nsizeof(true_2D) = %d\n", sizeof(true_2D)/sizeof(int));
return 0;
}