Allocating a 2D array using calloc - c

I am trying to dynamically allocate a 2D array using calloc.
Here is the code that I have tried.
int ** numberOfConstPiArray = calloc(invariannumberOfUniqueKernels * kernelColumnCount, sizeof(int *));
I have initialised the following variables as shown
int numberOfUniqueKernels = 100;
int kernelColumnCount = 10;
int dimensionalMatrixColumnCount = 10;
The following is the main code which loops through and tries to alter the 2D array.
for (int countKernel = 0; countKernel < numberOfUniqueKernels; countKernel++)
{
int countNumberOfConst = 0;
int numberOfTerms = 0;
int numberOfConstPi = 0;
for (int col = 0; col < kernelColumnCount; col++)
{
for (int row = 0; row < dimensionalMatrixColumnCount; row++)
{
if (some condition is satisfied)
{
countNumberOfConst += 1;
}
if (another condition satisfied)
{
numberOfTerms += 1;
}
}
if(countNumberOfConst == numberOfTerms)
{
numberOfConstPi += 1;
numberOfConstPiArray[countKernel][col] = 1;
}
countNumberOfConst=0;
numberOfTerms=0;
}
}
This doesn't seem to work. I understand that doesn't seem to work is vague but as this code is a part of a large compiler, there is no way for me to print out the specific output. Apologies for that.
My question is: Have I initialised the arrays in the correct way and have is the way I modified the values of the elements in the array correct.
Thank you.

This
int ** numberOfConstPiArray = calloc(invariannumberOfUniqueKernels * kernelColumnCount, sizeof(int *));
is not an allocation of a two-dimensional array because at least the type of numberOfConstPiArray is int ** instead of for example int ( * )[kernelColumnCount].
If your compiler supports variable length arrays then you could use the following approach as it is shown in the demonstrative program
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
size_t n = 5;
int ( *a )[n] = calloc( n * n, sizeof( int ) );
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < n; j++ ) a[i][j] = i * n + j;
}
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < n; j++ ) printf( "%2d ", a[i][j] );
putchar( '\n' );
}
free( a );
return 0;
}
The program output is
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
Or you can allocate an array of arrays the following way.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
size_t n = 5;
int **a = calloc( n, sizeof( int * ) );
for ( size_t i = 0; i < n; i++ )
{
a[i] = calloc( n, sizeof( int ) );
}
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < n; j++ ) a[i][j] = i * n + j;
}
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < n; j++ ) printf( "%2d ", a[i][j] );
putchar( '\n' );
}
for ( size_t i = 0; i < n; i++ )
{
free( a[i] );
}
free( a );
return 0;
}
The program output is the same as shown above.

numberOfConstPiArray[countKernel][col]
is getting an int* from numberOfConstPiArray[countKernel], then trying to dereference col'th element of this int*, and fails, as numberOfConstPiArray[countKernel] was not initialized with an reference to int array memory.
You may use instead:
int * numberOfConstPiArray = calloc(invariannumberOfUniqueKernels * kernelColumnCount, sizeof(int));
memset(numberOfConstPiArray, 0, invariannumberOfUniqueKernels * kernelColumnCount, sizeof(int));
...
numberOfConstPiArray[countKernel * kernelColumnCount + col] = 1;

Related

Insertion sort algorithm in C is not working

I am trying to sort an array of integers for finding the median of the same array. The code I am using sorts only the first two elements of the 10 element array. I have cross checked the swapping of variables in the loops, but everything seems okay.
void sort(int *arr) {
//get the size of this array
int size = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < size; i++) {
for (int j = i + 1; j < size; j++) {
if (arr[i] > arr[j]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
Application
#include <stdlib.h>
#include <stdio.h>
int main() {
int numbers[10];
numbers[0] = 10;
numbers[1] = 9;
numbers[2] = 8;
numbers[3] = 7;
numbers[4] = 6;
numbers[5] = 5;
numbers[6] = 4;
numbers[7] = 3;
numbers[8] = 2;
numbers[9] = 1;
sort(numbers);
//code sorts the element in the first and second index, the rest are unsorted please help
return 0;
}
What am I doing wrong?
The function parameter has a pointer type
void sort(int* arr){
Even if you will rewrite the function declaration like
void sort( int arr[10] ){
nevertheless the compiler will adjust the function parameter having the array type to pointer to the element type as it is written in your original function declaration
void sort(int* arr){
And in this call of the function
sort(numbers);
the array designator is implicitly converted to a pointer to its first element. That is the call above in fact is the same as
sort( &numbers[0] );
So using the operator sizeof with a pointer expression yields the size of a pointer. That is this line
//get the size of this array
int size=sizeof(arr)/sizeof(arr[0]);
is equivalent to
//get the size of this array
int size=sizeof( int * )/sizeof( int );
and yields either 2 or 1 depending on the used system.
You need to declare the function like
void sort( int *arr, size_t n );
and pass to the function the number of elements in the array explicitly.
Bear in mind that in general the user can use the function for a dynamically allocated array.
Pay attention to that the used by you algorithm is not the insertion sort algorithm. It is the selection sort algorithm with redundant swaps.
A function that implements the insertion sort algorithm can look for example the following way as it is shown in the demonstration program below.
#include <stdio.h>
void insertion_sort( int a[], size_t n )
{
for ( size_t i = 1; i < n; i++ )
{
int current = a[i];
size_t j = i;
for ( ; j != 0 && current < a[j - 1]; j-- )
{
a[j] = a[j - 1];
}
if ( j != i ) a[j] = current;
}
}
int main()
{
int a[] = { 9,8, 7, 6, 5, 4, 3, 2, 1, 0 };
const size_t N = sizeof( a ) / sizeof( *a );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
insertion_sort( a, N );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
The program output is
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
As for the function that implements the selection sort algorithm then without redundant swaps it can look the following way as it is shown in the next demonstration program.
#include <stdio.h>
void selection_sort( int a[], size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
size_t min = i;
for ( size_t j = i + 1; j < n; j++ )
{
if (a[j] < a[min]) min = j;
}
if ( min != i )
{
int tmp = a[i];
a[i] = a[min];
a[min] = tmp;
}
}
}
int main()
{
int a[] = { 9,8, 7, 6, 5, 4, 3, 2, 1, 0 };
const size_t N = sizeof( a ) / sizeof( *a );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
selection_sort( a, N );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
The program output is the same as shown above
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
This is because int size = sizeof(arr) / sizeof(arr[0]); will return 2, because sizeof(arr) will give the sizeof a pointer to int, which in your case is 8 bytes and then sizeof(arr[0]) will give a sizeof int which in your case is 4 bytes.
So,
8 / 4 = 2
Fix:
Add another parameter for the length of the array.
type-cast numbers to (int *) for sort() function
Your sort() function does not implement insertion sort algorithm, instead it is selection sort algorithm. READ MORE
There's no need of stdlib.h header file in your code
Like this: TRY IT ONLINE
#include <stdio.h>
void sort(int *arr, size_t len)
{
for (int i = 0; i < len; i++)
{
for (int j = i + 1; j < len; j++)
{
if (arr[i] > arr[j])
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
// using `const` keyword, because `arr` isn't modifying inside `print()` function
void print(const int *arr, size_t len){
for (size_t i = 0; i < len; i++)
{
printf("%d\n", arr[i]);
}
}
int main(void)
{
int numbers[10];
numbers[0] = 10;
numbers[1] = 9;
numbers[2] = 8;
numbers[3] = 7;
numbers[4] = 6;
numbers[5] = 5;
numbers[6] = 4;
numbers[7] = 3;
numbers[8] = 2;
numbers[9] = 1;
size_t len = sizeof(numbers) / sizeof(numbers[0]);
sort((int *)numbers, len);
print(numbers, len);
return 0;
}

selection sort isn't sorting correctly

My selection sort algorithm isn't working correctly. I've been stuck on this for quite a long time. I've solved it using pointers but for some reason it's sorting incorrectly.
void sortArray(int arr[], size_t n)
{
int i;
int j;
int min_idx;
int min;
for (i = 0; i < n - 2; i++)
{
min = arr[i];
min_idx = i;
for (j = (i+1); j < n - 1; j++)
{
if (arr[j] < arr[min])
{
min = arr[j];
min_idx = j;
}
}
//swap(arr[min_idx], arr[i]);
int temp = arr[min_idx];
arr[min_idx] = arr[i];
arr[i] = temp;
}
}
Before
10 9 8 7 6 5 4 3 0 0
After
0 9 7 3 6 4 5 8 10 0
But help would be appreciated.
There are at least two bugs in the function.
The first one is that the last element of the array with the index n-1 does not take part in sorting of the array due to conditions in the loops
for (i = 0; i < n - 2; i++)
{
min = arr[i];
min_idx = i;
for (j = (i+1); j < n - 1; j++)
//..
The second bug is that in this if statement
if (arr[j] < arr[min])
there is used min as an index instead of min_index in the operand arr[min].
Pay attention to that when n is equal to 0 or 1 then in the condition of the loop
for (i = 0; i < n - 2; i++)
the expression n - 2 will yield a big unsigned value that results in undefined behavior of the function.
And these variables
int i;
int j;
int min_idx;
shall have the type size_t instead of the type int.
Also declare variables in the minimum scope where they are used.
The function can be defined the following way.
void sortArray( int arr[], size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
size_t min_idx = i;
for ( size_t j = i + 1; j < n; j++ )
{
if ( arr[j] < arr[min_idx] )
{
min_idx = j;
}
}
if ( i != min_idx )
{
int temp = arr[min_idx];
arr[min_idx] = arr[i];
arr[i] = temp;
}
}
}
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void sortArray( int arr[], size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
size_t min_idx = i;
for ( size_t j = i + 1; j < n; j++ )
{
if ( arr[j] < arr[min_idx] )
{
min_idx = j;
}
}
if ( i != min_idx )
{
int temp = arr[min_idx];
arr[min_idx] = arr[i];
arr[i] = temp;
}
}
}
int main(void)
{
srand( ( unsigned int )time( NULL ) );
while ( 1 )
{
printf( "Enter the size of an integer array: " );
size_t n = 0;
if ( scanf( "%zu", &n ) != 1 || n == 0 ) break;
putchar( '\n' );
int a[n];
for ( size_t i = 0; i < n; i++ )
{
a[i] = rand() % n;
}
printf( "Source array: " );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
sortArray( a, n );
printf( "Sorted array: " );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
putchar( '\n' );
}
return 0;
}
Its output might look like
Enter the size of an integer array: 10
Source array: 4 1 1 3 1 8 7 4 0 9
Sorted array: 0 1 1 1 3 4 4 7 8 9
Enter the size of an integer array: 0
Your inner if is using the wrong index. It should be
if (arr[j] < arr[min_idx])
or, since arr[min_idx] is already stored in min
if (arr[j] < min)
You're also one index short in your sorting. You never look at arr[n - 1].
There are three small errors.
Two off by one errors on your loop conditions, and one variable name error (min instead of min_idx).
Fixing these three errors gives us...
void sortArray(int arr[], size_t n)
{
int i;
int j;
int min_idx;
for (i = 0; i < n - 1; i++)
{
min_idx = i;
for (j = (i+1); j < n; j++)
{
if (arr[j] < arr[min_idx])
{
min_idx = j;
}
}
//swap(arr[min_idx], arr[i]);
int temp = arr[min_idx];
arr[min_idx] = arr[i];
arr[i] = temp;
}
}
Also removed the unused min variable.

How to take input for multidimensional array and print the array in C using pointers?

I am trying to take integer data and store it into a dimensional array but i am unable to do it. Somebody help me please..
I tried using *(*(arr+i) + j) where arr is a pointer to the 2-D array , i and j are the loop variables,
I get an error
error: invalid type argument of unary '*' (have 'int') scanf("%d", ((arr+i) + j));
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
int n,*arr,i,j,k;
scanf("%d",&n);
arr = malloc(n*n*sizeof(int));
memset(arr,0,n*n*sizeof(int));
for(i=0;i<n;i++){
for(j=0;j<n;j++){
scanf("%d", *(*(arr+i) + j));
}
}
for(i=0;i<n;i++){
for(j=0;j<n;j++){
printf("%d ", *(*(arr+i) + j);
}
printf("\n");
}
}
My input was:
3
11 2 4
4 5 6
10 8 -12
int* arr ... arr = malloc(n*n*sizeof(int)); gives you a "mangled" 2D array - it's actually a 1D array. Meaning you'll have to access it as arr[i*n + j].
Mangled arrays are mostly a thing of the past though. With modern standard C, you can replace the whole code with this:
int (*arr)[n] = malloc( sizeof(int[n][n]) );
...
for(size_t i=0; i<n; i++)
for(size_t j=0; j<n; j++)
scanf("%d", &arr[i][j]);
...
free(arr);
Also note, if you need to zero-initialize the whole array to zero, you are better off using calloc since it does just that.
The type of the variable arr is int *.
int n,*arr,i,j,k;
^^^^
So there is no a two-dimensional array in your program.
So for example this expression
*(arr+i) + j
has type int. And this expression
*(*(arr+i) + j)
tries to dereference an object of the type int that is an object that is not a pointer.
If your compiler supports variable length arrays then the program can look like
#include <stdio.h>
int main(void)
{
size_t n;
scanf( "%zu", &n );
int a[n][n];
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < n; j++ )
{
scanf( "%d", *( a + i ) + j );
}
}
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < n; j++ )
{
printf( "%3d ", *( *( a + i ) + j ) );
}
putchar( '\n' );
}
return 0;
}
Its output is
11 2 4
4 5 6
10 8 -12
Otherwise another approach is dynamically to allocate a one-dimensional array of pointers and then correspondingly one-dimensional arrays of integers.
For example
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
size_t n;
scanf( "%zu", &n );
int **a = malloc( n * sizeof( int * ) );
for ( size_t i = 0; i < n; i++ )
{
*( a + i ) = malloc( n * sizeof( int ) );
}
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < n; j++ )
{
scanf( "%d", *( a + i ) + j );
}
}
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < n; j++ )
{
printf( "%3d ", *( *( a + i ) + j ) );
}
putchar( '\n' );
}
for ( size_t i = 0; i < n; i++ )
{
free( *( a + i ) );
}
free( a );
return 0;
}
The program output will be the same as shown above.

Passing matrix as a parameter

I am new to c, I am using CUDA compiler. I want to declare five matrices, from a[1][1] to a[5][5]. Initialize them with random values. Print these values. I have shown the whole code I wrote. I face problems
Passing matrix as parameter
Initialize a matrix (should be constant)
#include <stdio.h>
#include <stdlib.h>
void printMatrix(int **a, int rows, int cols)
{
for(int i=0; i<rows; i++){
for (int j=0; j<cols; j++){
printf("%d\t", a[i][j] );
}
printf("\n");
}
}
int main() {
int N;
for (int n=0; n<=5; n++)
N = n;
int a[N][N];
for(int i=0; i<N; i++)
for (int j=0; j<N; j++){
a[i][j] = rand() % 256;
}
printf("Matrix A\n");
printMatrix(a, 10, 10);
}
}
This works fine if i define N on the top. If I did that, I couldn't change N value using for loop. How can I correct.
For starters there is a typo in the program. You omitted the open brace after the loop statement
for (int n=0; n<=5; n++)
^^^^
N = n;
int a[N][N];
//...
There should be
for (int n=0; n<=5; n++) {
^^^^
N = n;
int a[N][N];
//...
Array a is a variable length array. Its dimension may not be equal to 0. So the variable n must to start from 1 as it is written in the assignment
for (int n=1; n<=5; n++) {
^^^^
This function call
printMatrix(a, 10, 10);
^^ ^^
does not make sense because the number 10 has nothing common with the array.
And the function declaration
void printMatrix(int **a, int rows, int cols);
^^^^^^^
is invalid. There is a mismatch between the argument type and the parameter type and there is no implicit conversion from one type to another type.
The program can look like
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void printMatrix( size_t rows, size_t cols, int a[][cols] )
{
for ( size_t i = 0; i < rows; i++ )
{
for ( size_t j = 0; j < cols; j++ ) printf( "%3d ", a[i][j] );
printf( "\n" );
}
}
int main( void )
{
const size_t N = 5;
const int UPPER_VALUE = 256;
srand( ( unsigned int )time( NULL ) );
for ( size_t n = 1; n <= N; n++ )
{
int a[n][n];
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < n; j++ ) a[i][j] = rand() % UPPER_VALUE;
}
printf( "Matrix A[%zu][%zu]:\n", n, n );
printMatrix( n, n, a );
printf( "\n" );
}
return 0;
}
Its output might be
Matrix A[1][1]:
117
Matrix A[2][2]:
57 216
50 233
Matrix A[3][3]:
42 117 215
177 218 26
202 81 163
Matrix A[4][4]:
205 178 157 2
229 165 93 94
91 160 39 205
26 242 131 69
Matrix A[5][5]:
147 248 126 107 42
103 149 160 62 70
122 89 17 203 252
222 125 154 224 98
63 61 192 155 222
If the compiler does not support variable length arrays then you have to allocate the arrays dynamically. For example
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void printMatrix( int **a, size_t rows, size_t cols )
{
for ( size_t i = 0; i < rows; i++ )
{
for ( size_t j = 0; j < cols; j++ ) printf( "%3d ", a[i][j] );
printf( "\n" );
}
}
int main( void )
{
const size_t N = 5;
const int UPPER_VALUE = 256;
srand( ( unsigned int )time( NULL ) );
for ( size_t n = 1; n <= N; n++ )
{
int **a = malloc( n * sizeof( int * ) );
for ( size_t i = 0; i < n; i++ )
{
a[i] = malloc( n * sizeof( int ) );
for ( size_t j = 0; j < n; j++ ) a[i][j] = rand() % UPPER_VALUE;
}
printf( "Matrix A[%zu][%zu]:\n", n, n );
printMatrix( a, n, n );
printf( "\n" );
for ( size_t i = 0; i < n; i++ ) free( a[i] );
free( a );
}
return 0;
}
for (int n=0; n<=5; n++){ /* <--missing { which causes N to be 6 after last iteration */
//your code
}
You missed a { after first for loop in main that's why int a[N][N] and other loops are not inside its body (which you probably want "changing value of N ")
It seems that the number of matrices is constant, so just #define it at the top. Without touching your printMatrix method, you can have a main body as follows:
#define N 5
int main(int argc, char ** argv)
{
int **data[N]; // Array of length N of int **, where each int ** will store a matrix.
for (int i = 0; i < N; i++) {
int matrixSize = i + 1; // creating the ith matrix
data[i] = malloc(matrixSize * sizeof *data[i]);
for (int j = 0; j < matrixSize; j++) {
data[i][j] = malloc(matrixSize * sizeof *data[i][j]);
for (int k = 0; k < matrixSize; k++) {
data[i][j][k] = rand() % 256;
}
}
}
// Printing the first one
printMatrix(data[0], 1, 1);
// don't forget to loop again to free the buffers allocated...
return 0;
}

Allocate memory for two dimensional array of integers but it should be continuous

I want to allocate memory to two dimensional array of type int but, the memory should be continuous.
it should be freed by just making one call to free( ptr ). I should need not to call free to each block of memory.
Formally, it is done like this:
int (*arr_ptr) [x][y] = malloc( sizeof(int[x][y]) );
(*arr_ptr)[i][j] = something; // access one element
free(arr_ptr);
However, this makes access of the elements a bit inconvenient: (*arr_ptr)[i][j] is a bit hard to read. A trick to avoid this, is to leave out one dimension of the array pointer and instead regard it as an array of one-dimensional arrays:
int (*arr_ptr) [y] = malloc( sizeof(int[x][y]) );
arr_ptr[i][j] = something; // access one element
free(arr_ptr);
If you have an ancient compiler, you must create a more ugly, "mangled" 2D array:
int* ptr = malloc( sizeof(int) * x * y );
ptr[i*y + j] = something; // access one element
free(ptr);
If your compiler supports Variable Length Arrays (VLAs) then you can write the following way
#include <stdlib.h>
#include <stdio.h>
int main( void )
{
size_t m = 3;
size_t n = 4;
int ( *a )[n] = malloc( m * n * sizeof( int ) );
for ( size_t i = 0; i < m; i++ )
{
for ( size_t j = 0; j < n; j++ ) a[i][j] = i * n + j;
}
for ( size_t i = 0; i < m; i++ )
{
for ( size_t j = 0; j < n; j++ ) printf( "%2d ", a[i][j] );
printf( "\n" );
}
free( a );
return 0;
}
The program output is
0 1 2 3
4 5 6 7
8 9 10 11
Otherwise n must be a constant. For example
#include <stdlib.h>
#include <stdio.h>
#define N 4
int main( void )
{
size_t m = 3;
int ( *a )[N] = malloc( m * N * sizeof( int ) );
for ( size_t i = 0; i < m; i++ )
{
for ( size_t j = 0; j < N; j++ ) a[i][j] = i * N + j;
}
for ( size_t i = 0; i < m; i++ )
{
for ( size_t j = 0; j < N; j++ ) printf( "%2d ", a[i][j] );
printf( "\n" );
}
free( a );
return 0;
}
Another possibility is to use a one dimensional array as a two dimensional one, like in the following example:
#include <stdio.h>
#include <stdlib.h>
#define N 2
#define M 3
/*
array has N * M elemts:
| N | N | N |
v v v v
|----|----|----|----|----|----|
array[i][j] == array[i*N + j]
*/
#define GET(i,j) (i*N + j)
int main(int argc, char **argv) {
int *array;
int i, j;
array = malloc(N * M *sizeof(int));
for (i = 0; i < N; i++)
for (j = 0; j < M; j++)
array[i*N + j] = i+j;
for (i = 0; i < N; i++)
for (j = 0; j < M; j++)
printf("array[%d][%d] = %d\n", i, j, array[i*N + j]);
printf("Using the macro:\n");
for (i = 0; i < N; i++)
for (j = 0; j < M; j++)
printf("array[%d][%d] = %d\n", i, j, array[GET(i,j)]);
free(array);
return 0;
}
I also defined a macro GET(i,j) so that the code will be more readable, actually this is really needed only to handle more complex cases then the two dimensional one.

Resources