Segfault in C (during middle of for loops) - c

I'm trying to practice C by writing a memory-type card game. The game is compiled by gcc on ARMv8. The user enters a number "users_N" in the argument line and a board of cards is created size: 2N x 2N.
The program runs just fine when the number is 1 or 2. But if it's 3 or bigger, I get a segmentation fault when trying to initialize the board. I thought this meant it was a stack overflow, but I increased the stack size to unlimited on my SSH and the problem was not resolved. I don't think it's a problem with pointers or trying to access an array out-of-bounds either, as it runs just fine until after 10 cards are added to the array.
The print statements are just to determine exactly when the segfault occurs.See image of for loop segfault
EDIT: to add more context... I know it's a bit messy, sorry!
int main(int argc, char *argv[]) {
if (argc < 3){ //Checking user's command line input.
printf("Missing argument. Exiting... \n");
return 0;
}
users_N = atoi(argv[2]);
srand(time(NULL)); //Initialize random number generator.
int ***board = (int ***)malloc(2 * users_N * sizeof(int)); //Dynamic array to store the board values
for (int i = 0; i < 2 * users_N; i++){
board[i] = (int **)malloc(2 * users_N * sizeof(int)); /*Array of pointers (rows) filled with
an array (columns). */
for (int j = 0; j < 2 * users_N; j++){
board[i][j] = (int *)malloc(2 * sizeof(int)); //3rd dimension to show/hide cards.
}
}
initialize(board);
}
/*
* Function initialize sets up the board. It takes the 3D board array. A card deck is created the
* size of 2N^2, then shuffled and added to the board. The 3rd dimension is initialized
* completely to 1, so all cards are shown. There is no return.
*/
void initialize(int*** board){
int* cards = (int *)malloc(2 * users_N * users_N * sizeof(int)); //Create an array of cards.
printf("Cards created\n");
for (int c = 0; c < (2 * users_N * users_N); c++){
printf("card: %d\n",c);
cards[c]=c;
}
int half = 0;
while (half < 2){ //Divide up into 2 halves of the board, to repeat shuffle and card placement.
shuffle(cards);
int cardsNum = 0;
for (int j = 0; j < users_N; j++){ //For each row in the current half:
printf("\n row = %d ", j);
for (int k = 0; k < (users_N * 2); k++){ //For each column:
printf("col = %d ",k);
board[j + (half * users_N)][k][0] = cards[cardsNum]; /* Assign appropriate
card to each board
position. */
printf("set to: %d ", board[j + (half * users_N)][k][0]);
board[j + (half * users_N)][k][1] = 1;
cardsNum++;
printf("Card num: %d \n", cardsNum);
}
}
half++; //Moves to next half to repeat.
}
}
/*
* Function shuffle takes the array of cards as a parameter. It will then randomly mix array.
* Numbers are not repeated and will not exceed 2N*N-1. No return values.
*/
void shuffle(int *cards){
int j;
for (int k = 0; k < (2 * users_N * users_N) - 2; k++){
j = randomNum(k, (2 * users_N * users_N) - 1); //Assign a random number between k and 2N*N-1.
swap(cards, k, j);
printf("cards swapped: %d,%d\n",k,j);
}
}
/*
* Function swap takes the array of cards, two index integers. The index integers indicate the positions of
* the elements (cards) to switch. No return values.
*/
void swap(int *cards, int i, int j){
int temp = cards[i]; //Value of position i stored in temp.
cards[i] = cards[j]; //value of card j assigned to card i.
cards[j] = temp; //Value of temp assigned to card j.
}

Allocation of your board is wrong:
int ***board = (int ***)malloc(2 * users_N * sizeof(int));
^^^^^^^^^^^
wrong size
for (int i = 0; i < 2 * users_N; i++){
board[i] = (int **)malloc(2 * users_N * sizeof(int));
^^^^^^^^^^^
wrong size
...
}
When you have board as int *** you don't want size of int during first allocation. You want size of int **. Like
int ***board = malloc(2 * users_N * sizeof(int**));
A better approach is to use the variable name - like:
int ***board = malloc(2 * users_N * sizeof *board);
^^^^^^
Better approach
to get correct size
The same applies to the next malloc

Related

Passing 3d arrays to a convolution function in C

I need to do a function that executes a 2D convolution and for that I need to pass to it a couple of 3d arrays. However I've been told my method is not an ideal way to do this.
First, I declare the variables:
typedef struct {
float img[224][224][3];
} input_224_t;
typedef struct {
float img[112][112][32];
} input_112_t;
typedef struct {
float img[3][3][32];
} weightsL1_t;
Then, the convolution looks like this:
void convolution(input_224_t* N, weightsL1_t* M, input_112_t* P, int size, int ksize, int channels, int filters, int stride)
{
// Effectively pads the image before convolution. Technically also works for pointwise, but it's inefficient.
// find center position of kernel (half of kernel size)
int kcenter = ksize / 2;
// Declare output indexes
int a = 0;
int b = -1;
for (int k = 0; k < filters; ++k) // filters
{
for (int i = 0; i < size; i = i + stride) // rows
{
for (int j = 0; j < size; j = j + stride) // columns
{
b++;
if (b == ksize) {b=0;a++;} // Increment output index
for (int m = 0; m < ksize; ++m) // kernel rows
{
for (int n = 0; n < ksize; ++n) // kernel columns
{
// Index of input signal, used for checking boundary
int ii = i + (m - kcenter);
int jj = j + (n - kcenter);
// Ignore input samples which are out of bound
if (ii >= 0 && ii < size && jj >= 0 && jj < size) {
for (int p = 0; p < channels; ++p) // channels
{
P.img[a][b][k] += N.img[ii][jj][p] * M.img[m][n][k]; // convolve
}
}
}
}
}
}
}
}
(This returns "field 'img' could not be resolved" at the "convolve" line)
I then import the values into the correct structs (which was a previous question of mine which has been answered: Write values to a 3D array inside a struct in C) and I call the function like this:
convolution(test_image, test_filter, test_result, 6, 3, 1, 1, 2);
I have been told in my previous question that this is not an ideal way to handle 3D arrays, and that it may use a lot more memory than I intend. This is a very memory-intensive process, and this will run in an embedded system, so optimizing memory allocation is paramount.
My objective, if possible, is to only allocate one of each of these 3D arrays at any point in time as to not use unnecessary memory, and do it in a way that this space can be freed at a later point.
Thank you in advance.
You could use Variable Length Arrays as function parameters.
void convolve(int isize, // width/height of input (224)
int osize, // width/height of output (112)
int ksize, // width/height of kernel (3)
int stride, // shift between input pixels, between consecutive outputs
int pad, // offset between (0,0) pixels between input and output
int idepth, int odepth, // number of input and output channels
float idata[isize][isize][idepth],
float odata[osize][osize][odepth],
float kdata[idepth][ksize][ksize][odepth])
{
// iterate over the output
for (int oy = 0; oy < osize; ++oy) {
for (int ox = 0; ox < osize; ++ox) {
for (int od = 0; od < odepth; ++od) {
odata[oy][ox][od] = 0;
for (int ky = 0; ky < ksize; ++ky) {
for (int kx = 0; kx < ksize; ++kx) {
// map position in output and kernel to the input
int iy = stride * oy + ky - pad;
int ix = stride * ox + kx - pad;
// use only valid inputs
if (iy >= 0 && iy < isize && ix >= 0 && ix < isize)
for (int id = 0; id < idepth; ++id)
odata[oy][ox][od] += kdata[id][ky][kx][od] * idata[iy][ix][id];
}}
}}}
}
Typical usage would be:
// allocate input
float (*idata)[224][3] = calloc(224, sizeof *idata);
// fill input using idata[y][x][d] syntax
// allocate kernel
float (*kdata)[3][3][32] = calloc(3, sizeof *kdata);
// fill kernel
// allocate output
float (*odata)[112][32] = calloc(112, sizeof *odata);
convolve(224, 112, 3, // input, output, kernel size
2, // stride
1, // pad input by one pixel what will center the kernel
3, 32, // number of input and output channels
idata, odata, kdata);
// free memory if it is no longer used
free(idata); free(odata); free(kdata);
The multidimentional arrays could be allocated with:
float (*arr)[10][20][30] = malloc(sizeof *arr);
however accessing elements is a bit cumbersome due to syntax (*arr)[i][j][j]. Therefore it is simple to use a pointer to the first element of array and allocate multiple subarrays at this pointer.
float (*arr)[20][30] = malloc(10 * sizeof *arr);
or with calloc() with automated zeroing and avoiding overflows.
float (*arr)[20][30] = calloc(10, sizeof *arr);
BTW. I suggest to reorder dimensions of the kernel to ODEPTH x KSIZE x KSIZE x IDEPTH. This would make iterating over the kernel more cache-friendly.

Can't point or store the elements of array in a new array

I have an arrFillRandom function which fill an array with random numbers and prints it out. Here it is:
void arrFillRandom(int *arrayPtr, int sizeRow, int sizeColumn, int randomRange) {
int i, j;
arrayPtr = malloc(sizeof(int) * sizeRow * sizeColumn);
for (i = 0; i < sizeRow; i++)
for (j = 0; j < sizeColumn; j++)
(arrayPtr + i)[j] = (rand() % randomRange);
for (i = 0; i < sizeRow; i++) {
printf("\n");
for (j = 0; j < sizeColumn; j++)
printf("%d\t", (arrayPtr + i)[j]);
}
}
And here is my main:
int main() {
void arrFillRandom(int *arrayPtr, int sizeRow, int sizeColumn, int randomRange);
int matrix1[2][3];
int matrix2[3][2];
int *ptr1, *ptr2;
ptr1 = &matrix1[0][0];
ptr2 = &matrix2[0][0];
arrFillRandom(ptr1, 2, 3, 10);
arrFillRandom(ptr2, 3, 2, 10);
printf("\n%d", ptr1[0]);
return 0;
}
My problem is that ptr1 or ptr2 doesn't point to array which arrFillRandom filled before.
In arrFillRandom function, I print out the matrix with random numbers. For example:
1, 0, 9 // first row of first matrix
0, 9, 4 // second row of first matrix
8, 2 // first row of second matrix
2, 5 // second row of second matrix
5, 5 // third row of second matrix
But in main, when I want to print first element of this matrix:
printf("\n%d", ptr1[0]);
This line should print 1, but it prints irrelevant number such as 4096.
So why I couldn't store that matrix in this array?
Your void arrFillRandom() function allocates new memory and fills that with
random numbers. arrayPtr is a local variable inside the function, and assigning a new value to it
does not change the passed arguments ptr1 or ptr2.
To fill the arrays whose addresses are passed to the function, simply remove the line
arrayPtr = malloc(sizeof(int) * sizeRow * sizeColumn);
You also have to change
(arrayPtr + i)[j]
to
arrayPtr[sizeColumn * i + j]
inside that function.

How do we allocate a 2-D array using One malloc statement

I have been asked in an interview how do i allocate a 2-D array and below was my solution to it.
#include <stdlib.h>
int **array;
array = malloc(nrows * sizeof(int *));
for(i = 0; i < nrows; i++)
{
array[i] = malloc(ncolumns * sizeof(int));
if(array[i] == NULL)
{
fprintf(stderr, "out of memory\n");
exit or return
}
}
I thought I had done a good job but then he asked me to do it using one malloc() statement not two. I don't have any idea how to achieve it.
Can anyone suggest me some idea to do it in single malloc()?
Just compute the total amount of memory needed for both nrows row-pointers, and the actual data, add it all up, and do a single call:
int **array = malloc(nrows * sizeof *array + (nrows * (ncolumns * sizeof **array));
If you think this looks too complex, you can split it up and make it a bit self-documenting by naming the different terms of the size expression:
int **array; /* Declare this first so we can use it with sizeof. */
const size_t row_pointers_bytes = nrows * sizeof *array;
const size_t row_elements_bytes = ncolumns * sizeof **array;
array = malloc(row_pointers_bytes + nrows * row_elements_bytes);
You then need to go through and initialize the row pointers so that each row's pointer points at the first element for that particular row:
size_t i;
int * const data = array + nrows;
for(i = 0; i < nrows; i++)
array[i] = data + i * ncolumns;
Note that the resulting structure is subtly different from what you get if you do e.g. int array[nrows][ncolumns], because we have explicit row pointers, meaning that for an array allocated like this, there's no real requirement that all rows have the same number of columns.
It also means that an access like array[2][3] does something distinct from a similar-looking access into an actual 2d array. In this case, the innermost access happens first, and array[2] reads out a pointer from the 3rd element in array. That pointer is then treatet as the base of a (column) array, into which we index to get the fourth element.
In contrast, for something like
int array2[4][3];
which is a "packed" proper 2d array taking up just 12 integers' worth of space, an access like array[3][2] simply breaks down to adding an offset to the base address to get at the element.
int **array = malloc (nrows * sizeof(int *) + (nrows * (ncolumns * sizeof(int)));
This works because in C, arrays are just all the elements one after another as a bunch of bytes. There is no metadata or anything. malloc() does not know whether it is allocating for use as chars, ints or lines in an array.
Then, you have to initialize:
int *offs = &array[nrows]; /* same as int *offs = array + nrows; */
for (i = 0; i < nrows; i++, offs += ncolumns) {
array[i] = offs;
}
Here's another approach.
If you know the number of columns at compile time, you can do something like this:
#define COLS ... // integer value > 0
...
size_t rows;
int (*arr)[COLS];
... // get number of rows
arr = malloc(sizeof *arr * rows);
if (arr)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < COLS; j++)
arr[i][j] = ...;
}
If you're working in C99, you can use a pointer to a VLA:
size_t rows, cols;
... // get rows and cols
int (*arr)[cols] = malloc(sizeof *arr * rows);
if (arr)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
arr[i][j] = ...;
}
How do we allocate a 2-D array using One malloc statement (?)
No answers, so far, allocate memory for a true 2D array.
int **array is a pointer to pointer to int. array is not a pointer to a 2D array.
int a[2][3] is an example of a true 2D array or array 2 of array 3 of int
To allocate memory for a true 2D array, with C99, use malloc() and save to a pointer to a variable-length array (VLA)
// Simply allocate and initialize in one line of code
int (*c)[nrows][ncolumns] = malloc(sizeof *c);
if (c == NULL) {
fprintf(stderr, "out of memory\n");
return;
}
// Use c
(*c)[1][2] = rand();
...
free(c);
Without VLA support, if the dimensions are constants, code can use
#define NROW 4
#define NCOL 5
int (*d)[NROW][NCOL] = malloc(sizeof *d);
You should be able to do this with (bit ugly with all the casting though):
int** array;
size_t pitch, ptrs, i;
char* base;
pitch = rows * sizeof(int);
ptrs = sizeof(int*) * rows;
array = (int**)malloc((columns * pitch) + ptrs);
base = (char*)array + ptrs;
for(i = 0; i < rows; i++)
{
array[i] = (int*)(base + (pitch * i));
}
I'm not a fan of this "array of pointers to array" to solve the multi dimension array paradigm. Always favored a single dimension array, at access the element with array[ row * cols + col]? No problems encapsulating everything in a class, and implementing a 'at' method.
If you insist on accessing the members of the array with this notation: Matrix[i][j], you can do a little C++ magic. #John solution tries to do it this way, but he requires the number of column to be known at compile time. With some C++ and overriding the operator[], you can get this completely:
class Row
{
private:
int* _p;
public:
Row( int* p ) { _p = p; }
int& operator[](int col) { return _p[col]; }
};
class Matrix
{
private:
int* _p;
int _cols;
public:
Matrix( int rows, int cols ) { _cols=cols; _p = (int*)malloc(rows*cols ); }
Row operator[](int row) { return _p + row*_cols; }
};
So now, you can use the Matrix object, for example to create a multiplication table:
Matrix mtrx(rows, cols);
for( i=0; i<rows; ++i ) {
for( j=0; j<rows; ++j ) {
mtrx[i][j] = i*j;
}
}
You should now that the optimizer is doing the right thing and there is no call function or any other kind of overhead. No constructor is called. As long as you don't move the Matrix between function, even the _cols variable isn't created. The statement mtrx[i][j] basically does mtrx[i*cols+j].
It can be done as follows:
#define NUM_ROWS 10
#define NUM_COLS 10
int main(int argc, char **argv)
{
char (*p)[NUM_COLS] = NULL;
p = malloc(NUM_ROWS * NUM_COLS);
memset(p, 81, NUM_ROWS * NUM_COLS);
p[2][3] = 'a';
for (int i = 0; i < NUM_ROWS; i++) {
for (int j = 0; j < NUM_COLS; j++) {
printf("%c\t", p[i][j]);
}
printf("\n");
}
} // end of main
You can allocate (row*column) * sizeof(int) bytes of memory using malloc.
Here is a code snippet to demonstrate.
int row = 3, col = 4;
int *arr = (int *)malloc(row * col * sizeof(int));
int i, j, count = 0;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
*(arr + i*col + j) = ++count; //row major memory layout
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
printf("%d ", *(arr + i*col + j));

Loop will not increment past 8?

I have a loop that involves a dynamically allocated array in C. For some reason it crashes after flag increments 7 times. This wasn't happening before I was reallocating the size of the array. Here is the code:
for (int i = 0; i < length-1; i++)
{
if (audio_samples[i] > threshold && run)
{
*event_flags = (int*)realloc(*event_flags, sizeof(int)*(flag+1)); // reallocate the size of the array
*event_flags[flag] = i;
// printf("FLAG CREATED! %i\n ", i);
printf("EVENT FLAG %i %i\n",flag, *event_flags[flag] );
if (flag >5) {
printf("%d\n", i);
}
flag++;
run = false;
}
Any ideas? Please keep in mind that the size of the array is indeed the same value as length. Here is an example of my errors:
EDIT 1
FILE ONE:
int *event_positions = (int *) malloc(1 * sizeof(int)); // let us start with 1 and then add more within the method. This should continue until we have all the flags we want.
int number_of_flags = event_extractor(vocal_data, size, event_positions);
FILE TWO:
float g_THRESHOLD_FACTOR = 2.3; // THIS INCREASES THE THRESHOLD VALUE.
int event_extractor (int *audio_samples, unsigned int size_of_audio ,int *event_flags)
{
int length = (int)size_of_audio;
// * * * * * * * * * * * * * * * * * *
// RECTIFY VALUES (MAKE ABSOLUTE) (MAKE ALL POSITIVE)
int *rectified_audio = (int *) malloc(length * sizeof(int)); // I took this line from wave header reader. The number is the number of samples of the hip hop track.
make_values_absolute(audio_samples, length, rectified_audio);
// If I convert to signed ints here would the method run more efficiently?
// * * * * * * * * * * * * * * * * * * * *
// LOW PASS FILTER
int *lopass_samples = (int *) malloc(length * sizeof(int)); // I took this line from wave header reader. The number is the number of samples of the hip hop track.
lopass(rectified_audio, length,0.5, lopass_samples);
int number_of_flags = apply_threshold (lopass_samples, length, &event_flags);
printf("\n\n\n NUMBER OF EVENTS AAAA --- %d\n", number_of_flags);
for (int i = 0; i < number_of_flags; i++) {
printf("FLAG %i -- %d \n", i, event_flags[i]);
}
return number_of_flags;
}
int apply_threshold (int *audio_samples, unsigned int size_of_audio, int **event_flags)
{
int flag = 0; // this will be the number of flags that I have
bool run = true; // this will make sure that a minimum amount of time passes before I grab another flag. It's a guard.
int counter = 0; // this is the counter for the above guard.
printf("\n\nCURRENT MINIMUM TIME: 20100 SAMPLES \n\n");
// event_flags[0] = 1; // this first one is a dud. within the loop we will automatically start adding flags
int threshold = calculate_threshold_value(audio_samples, size_of_audio);
printf("\n\n this is the threshold %d \n\n", threshold);
int length = (int)size_of_audio;
printf("LENGTH OF VOCAL AUDIO %d \n", length );
for (int i = 0; i < length-1; i++)
{
if (audio_samples[i] > threshold && run)
{
// ** is this realloc working ?
// event_flags = (int*)realloc(event_flags, sizeof(int) * (flag+1));
*event_flags = (int*)realloc(*event_flags, sizeof(int)*(flag+1)); // reallocate the size of the array
*event_flags[flag] = i;
// printf("FLAG CREATED! %i\n ", i);
printf("EVENT FLAG %i %i\n",flag, *event_flags[flag] );
if (flag >5) {
printf("%d\n", i);
}
flag++;
run = false;
}
if (!run) {
counter++;
if (counter > 20100) { // hardcode minimum size for now.
counter = 0;
run=true;
}
}
}
printf("\n\n\n NUMBER OF EVENTS --- %d\n", flag);
for (int i = 0; i < flag; i++) {
printf("FLAG %i -- %d\n", i, *event_flags[i]);
}
printf("\nFIVE samples before and after my second flag: \n 0 should indicate a reach in the threshold\n");
for (int i = 0; i <10 ; i++) {
printf("VOCAL SAMPLE %i %i \n", i-5,audio_samples[*event_flags[1]+i-5] );
}
return flag;
}
First you shouldn't cast the return of realloc.
Then if I suppose that the type of that variable is int*
*event_flags[flag] = i;
There is one * too much no?
Edit: After your remark on leaving out the cast.
So if your event_flags is effectively int**, you are really on the wrong track. Seeing your use, I would guess you simply want an array of int instead. If you do that and then
event_flags[flag] = i;
without * everywhere, your problem should go away.
If you really need that indirection, you'd have to allocate not only the array event_flags but also all the individual arrays these pointers are pointing to, with something like
for (size_t j = startvalue; j < something; ++j)
event_flags[j] = malloc(whatever);
I think you may have a problem with the precedence of the * operator versus the [] operator. That is *event_flags[flag] and (*event_flags)[flag] do not reference the same memory location. The first one correspond to **(event_flags + flag) (probably not accessible), while the second one correspond to *((*event_flags) + flag) (what you want).
So, you should rewrite your code to:
int** event_flags;
// ...
*event_flags = realloc(*event_flags, sizeof(int) * (flag + 1));
(*event_flags)[flag] = i;

Unknown error in the memory in C

I have a 2D dynamic array.
I enter a line of 0's after line which has a biggest number:
void InsertZero(int **a, int pos){
int i, j;
a = (int**)realloc(a, n * sizeof(*a));
a[n-1] = (int*)calloc(n, sizeof(**a));
d = 0;
for(i = n-1; i > pos; i--){
for(j = 0; j < n; j++){
a[i][j] = a[i-1][j];
printf("%d ", a[i][j]);
}
}
for(i = 0; i < n; i++){
a[pos][i] = 0;
}
}
If i make a size of array 3, 5, 7, 9, ... it works correctly. But if a number of lines is 2, 4, 6, ... , it is an access violation error, when i try to print my array:
void Print(void){
int i, j;
for(i = 0; i < (n-d); i++){
for(j = 0; j < n; j++){
printf("%d\t", arr[i][j]);
}
printf("\n");
}
}
code: http://codepad.org/JcUis6W4
Looking at this I cannot make sense of.... Look at comment 1, you have n set somewhere to realloc a block of memory which a is of type int ** - a double pointer, how are you calling this function? Secondly, comment 2, Why did you call calloc when the realloc on a double pointer was called previously...? Assume n has value of 5, then, realloc is called on double pointer a, meaning a[0][1]..a[4][1], now calloc is called thus a[4] has a new block of memory...
void InsertZero(int **a, int pos){
int i, j;
/* 1. */
a = (int**)realloc(a, n * sizeof(*a));
/* Bzzzzt....if realloc failed, a gets overwritten! */
/* 2. */
a[n-1] = (int*)calloc(n, sizeof(**a));
/* 3. */
d = 0;
/* 4. */
for(i = n-1; i > pos; i--){
for(j = 0; j < n; j++){
a[i][j] = a[i-1][j];
printf("%d ", a[i][j]);
}
}
for(i = 0; i < n; i++){
a[pos][i] = 0;
}
}
Comment 3, what is d used for - useless variable?
Comment 4, you are under the presumption that the block of memory has array subscripts [0][0] to [4][4] if n had a value of 5!
Can you clarify all this?
Edit: Looking at it again... it is likely that a got overwritten when the call to realloc failed! I recommend this section of code to counteract this
int **tmpA;
tmpA = (int**)realloc(a, n * sizeof(*a));
if (tmpA != NULL){
a = tmpA;
....
a[n-1] = (int*)calloc(n, sizeof(**a));
for(i = n-1; i > pos; i--){
....
}
for(i = 0; i < n; i++){
....
}
}
In your function InsertZero you have a local variable a. This local variable is initially set with a the address of a pointer to an integer (you probably wanted the address of a pointer to an array of integers, i.e. int ***a).
When you call realloc you are assigning your local copy of a a pointer to a block of memory, however once you have finished with your function it is entirely possible for your local copy of a to be pointing somewhere different to the rest of your program. You probably wanted to say *a = (int **)realloc(a, n * sizeof(int *));.
Dangerously, you're using n which isn't passed to your function. It appears you've made the assumption that n is going to be 1 bigger than the previous size of the array - otherwise your call to calloc is superfluous and you are just rotating the array letting the last element drop off as a memory leak.
Let's use a simpler example with no arrays, no dimensions. Let's say you wanted to create a function:
void make_me_a_pointer( int **mynumber ) {
*mynumber = (int *)malloc( sizeof(int) );
**mynumber = 7; /* assign the value 7 to my allocated memory */
}
int main( void ) {
int *demoint;
make_me_a_pointer( &demoint );
printf( "Magic num is %d\n", *demoint );
}
However in your case you merely assigned a = realloc... and thus never communicated the new address of a outside your function.

Resources