Printing 2d array initialized in a function but declared globally - c

I am trying to print a 2d array that has been declared globally as a double pointer and initialized inside a function in main(), but I get a core dump error.
What am I doing wrong here?
The array stored in the file:
1 2
3 4
5 6
Code:
#include <stdio.h>
#include <stdlib.h>
int** matrix_A = 0;
void initArray ( int** matrixPtr, FILE* matrixFP, int row, int col );
int main ( int argc, char* argv[] )
{
FILE* matrixAfp = fopen ( argv[1], "r" );
int M = atoi ( argv[3] );
int N = atoi ( argv[4] );
initArray ( matrix_A, matrixAfp, 3, 2 );
for ( size_t m = 0; m < M; m++ )
{
for ( size_t n = 0; n < N; n++ )
{
printf ( "%d \n", matrix_A[m][n] );
}
}
return 0;
}
void initArray ( int** matrixPtr, FILE* matrixFP, int row, int col )
{
matrixPtr = ( int** ) malloc ( row * sizeof ( int* ) );
for ( size_t m = 0; m < row; m++ )
{
matrixPtr[m] = ( int* ) malloc ( col * sizeof ( int ) );
}
for ( size_t n = 0; n < row; n++ )
{
for ( size_t o = 0; o < col; o++ )
{
fscanf ( matrixFP, "%d", &matrixPtr[n][o] );
}
}
}

The problem is that since you're passing matrix_A to the function by-value, matrixPtr is actually a copy of the global matrix_A, which means all the changes inside the function are happening to matrixPtr and not to globally-defined matrix_A.
To solve this, you can instead pass it by-reference:
void initArray(int** &matrixPtr, FILE *matrixFP, int row, int col)
Apart from that, this:
int M = atoi(argv[3]);
int N = atoi(argv[4]);
should be:
int M = atoi(argv[2]);
int N = atoi(argv[3]);

You pass the pointer by value, not by reference, so whatever you do with matrixPtr inside initArray will not make a difference outside the initArray-function. Try to modify the initArray(FILE *matrixFP, int row, int col) as followed,
int * initArray(FILE *matrixFP, int row, int col){
int m,n,o;
int **matrixPtr = (int **)malloc(row * sizeof(int *));
for (m = 0; m < row; m++) {
matrixPtr[m] = (int *)malloc(col * sizeof(int));
}
for (n = 0; n < row; n++) {
for (o = 0; o < col; o++) {
fscanf(matrixFP, "%d", &matrixPtr[n][o]);
}
}
return matrixPtr;
}
And using matrix_A=initArray(matrixAfp, 3, 2); in the main() to do the function call should work.

Related

To perform insert operation in a sorted array

What is wrong with this code and where is the problem?
I ran this code many times but it's showing that the code is running but I am not getting any output.
Can you tell me where is the mistake?
#include <stdio.h>
int print_arr(int *arr, int n)
{ for(int i=0; i<=n; i++)
{
printf("%d ",arr[i]);
}
return 0;
}
int insert_ele(int *arr_a, int *arr_b, int n, int Key)
{
int i,j;
for(i=0, j=0; i<n; i++, j++)
{
if(arr_a[i]>Key)
{
arr_b[j] = Key;
arr_b[j+1] = arr_a[i];
j++;
}
else
{
arr_b[j] = arr_a[i];
}
}
return 0;
}
int main()
{
//code
int arr_a[] = {12, 16, 20, 40, 50, 70};
int arr_b[10];
int Key = 26;
int n = sizeof(arr_a)/sizeof(arr_a[0]);
int indx = insert_ele(arr_a, arr_b, n, Key);
print_arr(arr, n);
return 0;
}
For starters there is a typo in this statement
print_arr(arr, n);
It seems you mean
print_arr( arr_b, n + 1 );
The return type int of the function print_arr does not make a sense and is useless.
The first parameter of the function should have the qualifier const because the passed array is not being changed within the function.
The second parameter should have the type size_t.
This for loop
for(int i=0; i<=n; i++)
can invoke undefined behavior if the user of the function will pass the number of elements in the array in the second parameter n because in this case there will be an attempt to access memory beyond the array.
Again the return type int of the function insert_ele does not make a sense and is useless.
The first parameter should have the qualifier const because the source array is not being changed within the function. The parameter n should have the type size_t.
The function has a logical error.
Let's assume that the value of the variable Key is less than values of all elements of the array arr_a.
In this case the index j will be incremented twice and as a result you will have
b[0] = Key; b[2] = Key; b[4] = Key; and so on.
The logic of the function will be much clear if to split the for loop in two for loops.
The program can look the following way.
#include <stdio.h>
size_t insert_ele( const int *a, size_t n, int *b, int key )
{
size_t i = 0;
for ( ; i < n && !( key < a[i] ); i++ )
{
b[i] = a[i];
}
b[i] = key;
for ( ; i < n; i++ )
{
b[i+1] = a[i];
}
return i;
}
FILE * print_arr( const int *a, size_t n, FILE *fp )
{
for ( size_t i = 0; i < n; i++)
{
fprintf( fp, "%d ", a[i] );
}
return fp;
}
int main(void)
{
int a[] = { 12, 16, 20, 40, 50, 70 };
const size_t N = sizeof( a ) / sizeof( *a );
int b[10];
int key = 26;
size_t m = insert_ele( a, N, b, key );
fputc( '\n', print_arr( b, m, stdout ) );
return 0;
}
The program output is
12 16 20 26 40 50

How can i pass a two dimensional array as an argument in C? [duplicate]

My function prototype is
int** rotate(int **arr, int row, int col, int fl);
where arr is the two dimensional array, row and col is the number of row and columns of the 2D array respectively, fl is a flag variable. If the value of fl is 0 then the array will be rotated right, if fl is 1 then the array will be rotated left.
I have called the function as follows:
int **res= rotate(arr, row, col, fl);
But I got one warning and one note
[Warning] passing argument 1 of 'rotate' from incompatible pointer type.
[Note] expected 'int **' but argument is of type 'int (*)[20]'
A pointer to a pointer is different from a pointer to an array. Array-to-pointer decaying can only happen on the left-most side (e.g. int [3][20] to int (*)[20]).
Change your function declaration to
int** rotate(int (*arr)[20], int row, int col, int fl);
or more obviously,
int** rotate(int arr[][20], int row, int col, int fl);
Note you have to fix the size at compile-time.
If your compiler supports variable length arrays then the function declaration can look the following way
void rotate( size_t row, size_t col, int arr[][col], int fl);
or
void rotate( size_t row, size_t col, int arr[][col], _Bool fl);
In this case you can use arrays with different sizes.
Here is a demonstrative program
#include <stdio.h>
void rotate( size_t row, size_t col, int a[][col], _Bool fl )
{
for ( size_t i = 0; i < ( fl ? row : col ); i++ )
{
for ( size_t j = 0; j < ( fl ? col : row ); j++ )
{
printf( "%d ", a[fl ? i : j][fl ? j : i] );
}
putchar( '\n' );
}
}
#define N1 3
int main(void)
{
int a[][3] =
{
{ 1, 2, 3 },
{ 4, 5, 6 }
};
rotate( sizeof( a ) / sizeof( *a ), N1, a, 0 );
putchar( '\n' );
rotate( sizeof( a ) / sizeof( *a ), N1, a, 1 );
putchar( '\n' );
return 0;
}
Its output is
1 4
2 5
3 6
1 2 3
4 5 6
Otherwise if within the function you are going to create new arrays then the function can look as it is shown in the following demonstrative program.
#include <stdio.h>
#include <stdlib.h>
int ** rotate( size_t, size_t, int a[][*], _Bool fl );
int ** rotate( size_t row, size_t col, int a[][col], _Bool fl )
{
int **p = malloc( col * sizeof( int * ) );
for ( size_t i = 0; i < col; i++ )
{
p[i] = ( int * )malloc( row * sizeof( int ) );
}
if ( fl )
{
for ( size_t i = 0; i < row; i++ )
{
for ( size_t j = 0; j < col; j++ )
{
p[col - j - 1][i] = a[i][j];
}
}
}
else
{
for ( size_t i = 0; i < row; i++ )
{
for ( size_t j = 0; j < col; j++ )
{
p[j][i] = a[row - i - 1][j];
}
}
}
return p;
}
#define M 2
#define N 3
int main(void)
{
int a[M][N] =
{
{ 1, 2, 3 },
{ 4, 5, 6 }
};
int **p = rotate( M, N, a, 0 );
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < M; j++ )
{
printf( "%d ", p[i][j] );
}
putchar( '\n' );
}
putchar( '\n' );
for ( size_t i = 0; i < N; i++ )
{
free( p[i] );
}
free( p );
p = rotate( M, N, a, 1 );
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < M; j++ )
{
printf( "%d ", p[i][j] );
}
putchar( '\n' );
}
putchar( '\n' );
for ( size_t i = 0; i < N; i++ )
{
free( p[i] );
}
free( p );
return 0;
}
Its output is
4 1
5 2
6 3
3 6
2 5
1 4
From the example, I assume that you are using a static definition of arr.
The Pointer to pointer is not the same as a 2D array.
Change
int** rotate(int **arr, int row, int col, int fl);
to
int** rotate(int arr[][20], int row, int col, int fl);
Note that the no of columns will have to be defined before compilation.

How to pass a two-dimensional array to a function in C?

My function prototype is
int** rotate(int **arr, int row, int col, int fl);
where arr is the two dimensional array, row and col is the number of row and columns of the 2D array respectively, fl is a flag variable. If the value of fl is 0 then the array will be rotated right, if fl is 1 then the array will be rotated left.
I have called the function as follows:
int **res= rotate(arr, row, col, fl);
But I got one warning and one note
[Warning] passing argument 1 of 'rotate' from incompatible pointer type.
[Note] expected 'int **' but argument is of type 'int (*)[20]'
A pointer to a pointer is different from a pointer to an array. Array-to-pointer decaying can only happen on the left-most side (e.g. int [3][20] to int (*)[20]).
Change your function declaration to
int** rotate(int (*arr)[20], int row, int col, int fl);
or more obviously,
int** rotate(int arr[][20], int row, int col, int fl);
Note you have to fix the size at compile-time.
If your compiler supports variable length arrays then the function declaration can look the following way
void rotate( size_t row, size_t col, int arr[][col], int fl);
or
void rotate( size_t row, size_t col, int arr[][col], _Bool fl);
In this case you can use arrays with different sizes.
Here is a demonstrative program
#include <stdio.h>
void rotate( size_t row, size_t col, int a[][col], _Bool fl )
{
for ( size_t i = 0; i < ( fl ? row : col ); i++ )
{
for ( size_t j = 0; j < ( fl ? col : row ); j++ )
{
printf( "%d ", a[fl ? i : j][fl ? j : i] );
}
putchar( '\n' );
}
}
#define N1 3
int main(void)
{
int a[][3] =
{
{ 1, 2, 3 },
{ 4, 5, 6 }
};
rotate( sizeof( a ) / sizeof( *a ), N1, a, 0 );
putchar( '\n' );
rotate( sizeof( a ) / sizeof( *a ), N1, a, 1 );
putchar( '\n' );
return 0;
}
Its output is
1 4
2 5
3 6
1 2 3
4 5 6
Otherwise if within the function you are going to create new arrays then the function can look as it is shown in the following demonstrative program.
#include <stdio.h>
#include <stdlib.h>
int ** rotate( size_t, size_t, int a[][*], _Bool fl );
int ** rotate( size_t row, size_t col, int a[][col], _Bool fl )
{
int **p = malloc( col * sizeof( int * ) );
for ( size_t i = 0; i < col; i++ )
{
p[i] = ( int * )malloc( row * sizeof( int ) );
}
if ( fl )
{
for ( size_t i = 0; i < row; i++ )
{
for ( size_t j = 0; j < col; j++ )
{
p[col - j - 1][i] = a[i][j];
}
}
}
else
{
for ( size_t i = 0; i < row; i++ )
{
for ( size_t j = 0; j < col; j++ )
{
p[j][i] = a[row - i - 1][j];
}
}
}
return p;
}
#define M 2
#define N 3
int main(void)
{
int a[M][N] =
{
{ 1, 2, 3 },
{ 4, 5, 6 }
};
int **p = rotate( M, N, a, 0 );
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < M; j++ )
{
printf( "%d ", p[i][j] );
}
putchar( '\n' );
}
putchar( '\n' );
for ( size_t i = 0; i < N; i++ )
{
free( p[i] );
}
free( p );
p = rotate( M, N, a, 1 );
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < M; j++ )
{
printf( "%d ", p[i][j] );
}
putchar( '\n' );
}
putchar( '\n' );
for ( size_t i = 0; i < N; i++ )
{
free( p[i] );
}
free( p );
return 0;
}
Its output is
4 1
5 2
6 3
3 6
2 5
1 4
From the example, I assume that you are using a static definition of arr.
The Pointer to pointer is not the same as a 2D array.
Change
int** rotate(int **arr, int row, int col, int fl);
to
int** rotate(int arr[][20], int row, int col, int fl);
Note that the no of columns will have to be defined before compilation.

reallocation of 2d arrays in c

I want to reallocate a 2d array, so that the arrays in the second array become bigger, so the things I want to store are bigger than the arrays I want to store them in and I want to make the arrays bigger. The problem is that I do not really know how to do this. I got it to compile without errors, but in Valgrind I saw a lot of memory errors, so I do something wrong. I saw a previous question about this here but I do not really understand it, so any help and explanation on how to do this would be greatly appreciated.
I have this so far.
int **create2darray(int a, int b) {
int i;
int **array;
array = malloc(a * sizeof(int *));
assert(array != NULL);
for (i = 0; i < a; i++) {
array[i] = calloc(b, sizeof(int));
assert(array[i] != NULL);
}
return array;
}
int **reallocArray(int **array, int size, int i) {
int i;
int **safe_array;
safe_array = realloc(*array ,2 * size);
assert(safe_array != NULL);
array = safe_array;
return array;
}
void free2DArray(int **array, int m) {
int i;
for (i = 0; i < m; i++) {
free(array[i]);
}
}
int main(int argv, char *argc[]) {
int i;
int size;
int **testArray = create2darray(1, 10);
size = 10;
for(i = 0; i < size; i++) {
testArray[0][i] = 2;
}
testArray[0] = reallocArray(testArray, size, 0);
size = 2 * size;
for(i = 9; i < size; i++) {
testArray[0][i] = 3;
}
for(i = 0; i < size; i++) {
printf("%d", testArray[0][i]);
free2DArray(testArray, size);
}
return 0;
}
You need a function reallocArray which realaoctes the outer array and all the inner arrays too.
Adapt youre code like this:
#include <malloc.h>
int **reallocArray( int **array, int oldSizeA, int newSizeA, int newSizeB )
{
// realloc the array of pointers ( allocates new memory if array == NULL )
int **safe_array = realloc( array, newSizeA * sizeof( int* ) );
assert(safe_array != NULL);
if ( safe_array == NULL )
return array;
array = safe_array;
// realloc the inner arrays of int ( allocates new memory if i >= oldSizeA )
for ( int i = 0; i < newSizeA; i ++ )
{
int *temp = NULL; // allocate new memory if i >= oldSizeA
if ( i < oldSizeA )
temp = array[i]; // reallocate array[i] if i < oldSizeA
temp = realloc( temp, newSizeB * sizeof( int ) );
assert( temp != NULL );
if ( temp == NULL )
return array;
array[i] = temp;
}
return array;
}
Use function reallocArray in your function create2darray to create your array. If the input paramter of ralloc is NULL, then new dynamic memory is allocated.
int **create2darray( int sizeA, int sizeB )
{
return reallocArray( NULL, 0, sizeA, sizeB );
}
First you have to free the inner arrays of int in a loop, then you have to free the array of pointers:
void free2DArray( int **array, int sizeA )
{
for (int i = 0; i < sizeA; i ++)
free( array[i] );
free( array );
}
int main( int argv, char *argc[] ){
int sizeA = 1;
int sizeB = 10;
int **testArray = create2darray( sizeA, sizeB );
for ( int i = 0; i < sizeB; i++ ) {
testArray[0][i] = 2;
}
int oldSizeA = sizeA;
int oldSizeB = sizeB;
sizeB = 2*sizeB;
testArray = reallocArray( testArray, oldSizeA, sizeA, sizeB );
for( int i = oldSizeB; i < sizeB; i++ ) {
testArray[0][i] = 3;
}
for( int i = 0; i < sizeB; i++ ) {
printf("%d", testArray[0][i]);
}
free2DArray(testArray, sizeA );
return 0;
}
In Free2DArray(), you free() the individual arrays of integers, but not the "outer" dimension of the array which holds the integer pointers.
You could add another call to free() after the loop to take care of that.
In main():
for(i = 0; i <size; i++) {
printf("%d", testArray[0][i]);
free2DArray(testArray, size);
}
you will end up free()-ing the (inner) integer arrays multiple times.
The call to free2DArray() should be outside the loop.

How can I create a function for dynamic allocation for 2d array in c? [duplicate]

This question already has answers here:
Allocate memory 2d array in function C
(8 answers)
C. Segmentation Fault when function modifies dynamically allocated 2d array
(3 answers)
Closed 8 years ago.
#include<stdio.h>
#include<stdlib.h>
void aloc_dinamic(double **M)
{
int i;
M = (double **)malloc(m*sizeof(double *));
for(i=0;i<m;i++)
M[i] = (double *)calloc(m, sizeof(double));
}
int main(void)
{
double **H;
aloc_dinamic(H)
}
How can I create a function for dynamic allocation for 2d array in c?
I tried this, but it doesn't work.
#include <stdlib.h>
double ** aloc_dynamic( size_t n, size_t m )
{
double **p = ( double ** )malloc( n * sizeof( double * ) );
for ( size_t i = 0; i < n; i++ )
{
p[i] = ( double * )malloc( m * sizeof( double ) );
}
return p;
}
int main(void)
{
size_t n = 5;
size_t m = 10;
double **p = aloc_dynamic( n, m );
// before exiting the function free the allocated memory
}
... and with the corresponding free function
#include<stdio.h>
#include<stdlib.h>
double** alloc_2d(int y_extent, int x_extent)
{
int y, x;
double ** array = (double**)malloc(y_extent * sizeof(double*));
for (y = 0 ; y < y_extent ; ++y) {
array[y] = (double*)malloc(sizeof(double) * x_extent);
for(x = 0 ; x < x_extent ; ++x) {
array[y][x] = 0.0;
}
}
return array;
}
void free_2d(double** array, int y_extent)
{
int y;
for(y = 0 ; y < y_extent ; ++y) {
free(array[y]);
}
free(array);
}
int main(void)
{
double **H = alloc_2d(50,100);
H[10][10] = 0.0; // for example
free_2d(H, 50);
return 0;
}
You can do it like this:
// We return the pointer
int **get(int N, int M) /* Allocate the array */
{
/* Check if allocation succeeded. (check for NULL pointer) */
int i, **table;
table = malloc(N*sizeof(int *));
for(i = 0 ; i < N ; i++)
table[i] = malloc( M*sizeof(int) );
return table;
}
// We don't return the pointer
void getNoReturn(int*** table, int N, int M) {
/* Check if allocation succeeded. (check for NULL pointer) */
int i;
*table = malloc(N*sizeof(int *));
for(i = 0 ; i < N ; i++)
*table[i] = malloc( M*sizeof(int) );
}
void fill(int** p, int N, int M) {
int i, j;
for(i = 0 ; i < N ; i++)
for(j = 0 ; j < M ; j++)
p[i][j] = j;
}
void print(int** p, int N, int M) {
int i, j;
for(i = 0 ; i < N ; i++)
for(j = 0 ; j < M ; j++)
printf("array[%d][%d] = %d\n", i, j, p[i][j]);
}
void free2Darray(int** p, int N) {
int i;
for(i = 0 ; i < N ; i++)
free(p[i]);
free(p);
}
int main(void)
{
int **p;
//getNoReturn(&p, 2, 5);
p = get(2, 5);
fill(p ,2, 5);
print(p, 2, 5);
free2Darray(p ,2);
return 0;
}
Remember a 2D array is a 1D array of pointers, where every pointer, is set to another 1D array of the actual data.
Image:
I suggest you to read the explanation here.

Resources