Here is my code. While choosing values, if I try to put 9 values it dumps garbage value. It has happened while doing quick sort as well
#include <stdio.h>
void printArray(int* A, int n) {
for (int i = 0; i < n; i++) {
printf("%d ", A[i]);
}
printf("\n");
}
int maximum(int A[],int n) {
int i, max = A[0];
for (i = 1; i < n; i++) {
if (A[i] > max) {
max = A[i];
}
}
return max;
}
void countSort(int A[], int n) {
int i, max = maximum(A, n);
int count[max + 1], B[n];
for (i = 0; i < max + 1; i++) {
count[i] = 0;
}
for (i = 0; i < max + 1; i++) {
count[A[i]]++;
}
for (i = 1; i < n; i++) {
count[i] += count[i - 1];
}
for (i = n - 1; i >= 0; i--) {
B[--count[A[i]]] = A[i];
}
for (i = 0; i < n; i++) {
A[i] = B[i];
}
}
int main(){
int A[] = {1, 4, 6, 2, 3, 2, 3, 2, 7};
int n = 9;
printArray(A, n); // Printing the array before sorting
countSort(A, n); // Function to sort the array
printArray(A, n); // Printing the array before sorting
return 0;
}
This code uses the wrong limit:
for(i=0;i<max+1;i++) {
count[A[i]]++;
}
It effectively iterates through the elements of A, which has n elements, not max+1.
This is a code for multiplying two square matrices in C.
What is the difference between using malloc and calloc in void multiply() function?
When using malloc, I am getting garbage values, but calloc is providing the right answer.
Only the first row is outputting garbage values so is it an issue with the way malloc allocates space in the heap as compared to calloc?
#include <stdio.h>
#include <stdlib.h>
int *getArray(int);
void display(int *, int, int);
void multiply(int *, int *, int);
int main() {
int n;
printf("enter dimension of square matrix:\n");
scanf("%d", &n);
int *arr1;
int *arr2;
arr1 = getArray(n);
display(arr1, n, n);
printf("\n now give input for next array");
arr2 = getArray(n);
display(arr2, n, n);
printf("\n\n\n");
multiply(arr1, arr2, n);
return 0;
}
int *getArray(int n) {
int *arr = (int *)malloc(n * n * sizeof(int));
printf("\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", (arr + i * n + j));
}
}
/*for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf(" %d ", *(arr + i * n + j));
}
printf("\n");
}*/
return arr;
}
void display(int *arr, int row, int col) {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
printf(" %d ", *(arr + i * row + j));
}
printf("\n");
}
}
void multiply(int *arr1, int *arr2, int n) {
int *arr = (int *)calloc(n * n, sizeof(int));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
*(arr + i * n + j) += (*(arr1 + i * n + k)) * (*(arr2 + k * n + j));
}
}
}
printf("product of above matrices = \n\n");
display(arr, n, n);
}
The only functional difference between allocating memory with malloc() and with calloc() for the same size, assuming the size computation is accurate, is the latter initializes the block to all bits 0, whereas the former does not.
All bits 0 means all int values in the array are initialized to 0.
The inner loop in the multiply function only increments the element at row i and column j, therefore the function relies on implicit initialization of the array elements to 0. calloc() does that, but not malloc() so you definitely need to use calloc().
Also note these remarks:
in display the computation for the offset of the matrix element at row i column j should be printf(" %5d ", *(arr + i * col + j));
multiply should return arr and display() should be called in the main function.
you should check for scanf(), malloc() and calloc()` failure
you should free allocated memory
pointer arguments to objects that are not modified by the function should be const qualified so the function can be called with a pointer to a const object.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
int *getArray(int);
void display(const int *, int, int);
int *multiply(const int *, const int *, int);
int main() {
int n;
printf("enter dimension of square matrix:\n");
if (scanf("%d", &n) != 1)
return 1;
printf("\n now give input for the first array");
int *arr1 = getArray(n);
if (!arr1)
return 1;
display(arr1, n, n);
printf("\n now give input for the second array");
int *arr2 = getArray(n);
if (!arr2)
return 1;
display(arr2, n, n);
printf("\n\n\n");
int *arr = multiply(arr1, arr2, n);
if (!arr)
return 1;
printf("product of above matrices = \n\n");
display(arr, n, n);
free(arr1);
free(arr2);
free(arr);
return 0;
}
int *getArray(int n) {
int *arr = malloc(sizeof(int) * n * n);
if (arr == NULL)
return NULL;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (scanf("%d", (arr + i * n + j)) != 1) {
free(arr);
return NULL;
}
}
}
return arr;
}
void display(const int *arr, int row, int col) {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
printf(" %5d ", *(arr + i * col + j));
}
printf("\n");
}
}
int *multiply(const int *arr1, const int *arr2, int n) {
int *arr = calloc((size_t)n * n, sizeof(int));
if (arr == NULL)
return NULL;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
*(arr + i * n + j) += (*(arr1 + i * n + k)) * (*(arr2 + k * n + j));
}
}
}
return arr;
}
I have a 2D array called matrix, now I would like to add one to every element.
#include <stdio.h>
#include <stdlib.h>
int **add_one(int **matrix, int m, int n) {
int i, j;
int **new_mat;
new_mat = (int **) malloc(m * n *sizeof(int));
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
new_mat[i][j] = matrix[i][j] + 1;
}
}
//return the 2nd rank pointer
return new_mat;
}
int main() {
int matrix[3][2] = {1, 2, 3, 4, 5, 6};
int **new_mat;
int i, j;
new_mat = add_one(matrix, 3, 2);
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++) {
printf("%d ", new_mat[i][j]);
}
printf("\n");
}
free(new_mat);
}
However, the compiler told me that
[Error] cannot convert 'int (*)[2]' to 'int**' for argument '1' to 'int** add_one(int**, int, int)'
It works a bit differently from what you thought
#include <stdio.h>
#include <stdlib.h>
// you can only pass what you have
int **add_one(int matrix[3][2], int m, int n)
{
int i, j;
int **new_mat;
// allocate m pointers (the rows)
new_mat = malloc(m * sizeof(*new_mat));
for (i = 0; i < m; i++) {
// allocate space for n ints
new_mat[i] = malloc(n * sizeof(int));
for (j = 0; j < n; j++) {
new_mat[i][j] = matrix[i][j] + 1;
}
}
//return the 2nd rank pointer
return new_mat;
}
int main()
{
// you forgot to encapsulate the rows, too
int matrix[3][2] = { {1, 2}, {3, 4}, {5, 6} };
int **new_mat;
int i, j;
new_mat = add_one(matrix, 3, 2);
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++) {
printf(" %d ", new_mat[i][j]);
}
printf("\n");
}
free(new_mat);
}
If you want to pass the two-star matrix as a two-star matrix you need to build it like the new_mat in the function add_one.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am a beginner in programming and just learned new concepts and started writing code for matrix multiplication but I got confused in pointers and others so I am uploading my code here in seek of guidelines.
#include <stdio.h>
#include <stdlib.h>
int **matrixMultiply(int A[][8], int B[][8], int row);
int main() {
int **A = allocate_matrix(A, 8, 8);
int **B = allocate_matrix(B, 8, 8);
int i, j;
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
A[i][j] = i + j;
A[i][j] = i + j;
}
}
int **C = allocate_matrix(C, 8, 8);
C = matrixMultiply(A, B, 8);
return 0;
}
int **matrixMultiply(int A[][8], int B[][8], int row) {
int **C = allocate_matrix(C, row, row);
if (row == 1) {
C[1][1] = A[1][1] * B[1][1];
} else {
int a11[row/2][row/2], a12[row/2][row/2], a21[row/2][row/2], a22[row/2][row/2];
int b11[row/2][row/2], b12[row/2][row/2], b21[row/2][row/2], b22[row/2][row/2];
int **c11 = allocate_matrix(c11, row/2, row/2);
int **c12 = allocate_matrix(c12, row/2, row/2);
int **c21 = allocate_matrix(c21, row/2, row/2);
int **c22 = allocate_matrix(c22, row/2, row/2);
int i, j;
for (i = 0; i < row/2; i++) {
for (j = 0; j < row/2; j++) {
a11[i][j] = A[i][j];
a12[i][j] = A[i][j + (row/2)];
a21[i][j] = A[i + (row/2)][j];
a22[i][j] = A[i + (row/2)][j + (row/2)];
b11[i][j] = B[i][j];
b12[i][j] = B[i][j + (row/2)];
b21[i][j] = B[i + (row/2)][j];
b22[i][j] = B[i + (row/2)][j + (row/2)];
c11[i][j] = C[i][j];
c12[i][j] = C[i][j + (row/2)];
c21[i][j] = C[i + (row/2)][j];
c22[i][j] = C[i + (row/2)][j + (row/2)];
}
}
c11 = addmatrix(matrixMultiply(a11, b11, row/2),
matrixMultiply(a12, b21, row/2), c11, row/2);
c12 = addmatrix(matrixMultiply(a11, b12, row/2),
matrixMultiply(a22, b22, row/2), c12, row/2);
c21 = addmatrix(matrixMultiply(a21, b11, row/2),
matrixMultiply(a22, b21, row/2), c21, row/2);
c22 = addmatrix(matrixMultiply(a21, b12, row/2),
matrixMultiply(a22, b22, row/2), c22, row/2);
// missing code???
return C;
}
}
int **allocate_matrix(int **matrix, int row, int column) {
matrix = (int **)malloc(row * sizeof(int*));
int i;
for (i = 0; i < row; i++) {
matrix[row] = (int *)malloc(row * sizeof(int));
}
return matrix;
}
void deallocate_matrix(int **matrix, int row) {
int i;
for (i = 0; i < row; i++) {
free(matrix[row]);
}
free(matrix);
}
int **addMatrix(int **a, int **b, int **c, int row) {
int i, j;
for (i = 0; i < row; i++) {
for (j = 0; j < row; j++) {
c[i][j] = a[i][j] + b[i][j];
}
}
return c;
}
I reformatted your code so I could analyze it. Indent consistently with 4 spaces, insert spaces around binary operators, after , and ; separators and between keywords and (, this improves readability a lot.
There seems to be missing code in the matrixMultiply function: you allocate the resulting matrix C but you use it as an input to initialize the intermediary matrices c11, c21, c21 and c22, and never actually store anything into C except for the trivial 1x1 case.
The matrix multiplication code seems broken beyond this, the function takes 2 arguments of type int A[][8], int B[][8], but you recursively call it with local arrays a11 to b22 defined as int a11[row/2][row/2]. These types are different, I do not know how the code even compiles.
In the matrix allocation code, you allocate rows with in incorrect size row instead of column. You should use calloc for this so the matrix is initialized to 0, plus you should not pass the initial argument at all:
int **allocate_matrix(int row, int column) {
int **matrix = malloc(row * sizeof(*matrix));
for (int i = 0; i < row; i++) {
matrix[i] = calloc(column, sizeof(*matrix[row]));
}
return matrix;
}
There is also a mistake for the second submatrix multiplication, it should be
c12 = addmatrix(matrixMultiply(a11, b12, row/2),
matrixMultiply(a12, b22, row/2), c12, row/2);
Furthermore, you never free the temporary matrices used for intermediary results. Unlike java, C does not have a garbage collector, you are responsible for releasing blocks of memory when you no longer need them, before they become inaccessible.
Here is a corrected version, with extra functions to print the matrix data and verify the matrix multiplication correctness. I added timings: the recursive method is much slower than the direct method, mostly because of all the extra allocation/deallocation for the intermediary results.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int **matrix_allocate(int row, int column) {
int **matrix = malloc(row * sizeof(*matrix));
for (int i = 0; i < row; i++) {
matrix[i] = calloc(column, sizeof(*matrix[i]));
}
return matrix;
}
void matrix_free(int **matrix, int row) {
for (int i = 0; i < row; i++) {
free(matrix[i]);
}
free(matrix);
}
void matrix_print(const char *str, int **a, int row) {
int min, max, w = 0, n1, n2, nw;
min = max = a[0][0];
for (int i = 0; i < row; i++) {
for (int j = 0; j < row; j++) {
if (min > a[i][j])
min = a[i][j];
if (max < a[i][j])
max = a[i][j];
}
}
n1 = snprintf(NULL, 0, "%d", min);
n2 = snprintf(NULL, 0, "%d", max);
nw = n1 > n2 ? n1 : n2;
for (int i = 0; i < row; i++) {
if (i == 0)
w = printf("%s = ", str);
else
printf("%*s", w, "");
for (int j = 0; j < row; j++) {
printf(" %*d", nw, a[i][j]);
}
printf("\n");
}
fflush(stdout);
}
int **matrix_add(int **a, int **b, int row, int deallocate) {
int **c = matrix_allocate(row, row);
for (int i = 0; i < row; i++) {
for (int j = 0; j < row; j++) {
c[i][j] = a[i][j] + b[i][j];
}
}
if (deallocate & 1) matrix_free(a, row);
if (deallocate & 2) matrix_free(b, row);
return c;
}
int **matrix_multiply(int **A, int **B, int row, int deallocate) {
int **C = matrix_allocate(row, row);
if (row == 1) {
C[0][0] = A[0][0] * B[0][0];
} else {
int row2 = row / 2;
int **a11 = matrix_allocate(row2, row2);
int **a12 = matrix_allocate(row2, row2);
int **a21 = matrix_allocate(row2, row2);
int **a22 = matrix_allocate(row2, row2);
int **b11 = matrix_allocate(row2, row2);
int **b12 = matrix_allocate(row2, row2);
int **b21 = matrix_allocate(row2, row2);
int **b22 = matrix_allocate(row2, row2);
for (int i = 0; i < row2; i++) {
for (int j = 0; j < row2; j++) {
a11[i][j] = A[i][j];
a12[i][j] = A[i][j + row2];
a21[i][j] = A[i + row2][j];
a22[i][j] = A[i + row2][j + row2];
b11[i][j] = B[i][j];
b12[i][j] = B[i][j + row2];
b21[i][j] = B[i + row2][j];
b22[i][j] = B[i + row2][j + row2];
}
}
int **c11 = matrix_add(matrix_multiply(a11, b11, row2, 0),
matrix_multiply(a12, b21, row2, 0), row2, 1+2);
int **c12 = matrix_add(matrix_multiply(a11, b12, row2, 1),
matrix_multiply(a12, b22, row2, 1), row2, 1+2);
int **c21 = matrix_add(matrix_multiply(a21, b11, row2, 2),
matrix_multiply(a22, b21, row2, 2), row2, 1+2);
int **c22 = matrix_add(matrix_multiply(a21, b12, row2, 1+2),
matrix_multiply(a22, b22, row2, 1+2), row2, 1+2);
for (int i = 0; i < row2; i++) {
for (int j = 0; j < row2; j++) {
C[i][j] = c11[i][j];
C[i][j + row2] = c12[i][j];
C[i + row2][j] = c21[i][j];
C[i + row2][j + row2] = c22[i][j];
}
}
matrix_free(c11, row2);
matrix_free(c12, row2);
matrix_free(c21, row2);
matrix_free(c22, row2);
}
if (deallocate & 1) matrix_free(A, row);
if (deallocate & 2) matrix_free(B, row);
return C;
}
int **matrix_multiply_direct(int **A, int **B, int row, int deallocate) {
int **C = matrix_allocate(row, row);
for (int i = 0; i < row; i++) {
for (int j = 0; j < row; j++) {
int x = 0;
for (int k = 0; k < row; k++) {
x += A[i][k] * B[k][j];
}
C[i][j] = x;
}
}
if (deallocate & 1) matrix_free(A, row);
if (deallocate & 2) matrix_free(B, row);
return C;
}
int main(int argc, char **argv) {
int n = argc < 2 ? 8 : atoi(argv[1]);
int **A = matrix_allocate(n, n);
int **B = matrix_allocate(n, n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
A[i][j] = i + j;
B[i][j] = i + j;
}
}
matrix_print("A", A, n);
matrix_print("B", B, n);
if ((n & (n - 1)) == 0) {
/* recursive method can be applied only to powers of 2 */
clock_t ticks = -clock();
int **C = matrix_multiply(A, B, n, 0);
ticks += clock();
matrix_print("C = A * B", C, n);
printf("%d ticks\n", ticks);
matrix_free(C, n);
}
clock_t ticks = -clock();
int **D = matrix_multiply_direct(A, B, n, 1+2);
ticks += clock();
matrix_print("D = A * B", D, n);
printf("%d ticks\n", ticks);
matrix_free(D, n);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
float average_score(int** array_score)
{
int i, j;
int sum = 0;
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
sum += *(*(array_score + i) + j);
}
}
printf("sum / 16 = %d\n", sum / 16);
return (float) sum / 16;
}
int lowest_score(int** array_score)
{
int i, j;
int temp = **array_score;
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
if(temp > *(*(array_score + i) + j))
//------
temp = *(*(array_score + i) + j);
printf("%d ",*(*(array_score + i) + j));
}
//--
printf("\n");
}
printf("low_score = %d\n", temp);
return temp;
}
int main(int argc, char** argv)
{
int **array_score = NULL;
int i = 0;
int j = 0;
//Create a two-dimensional array
array_score = (int **) malloc(4 * sizeof(int *));
for(i = 0; i <= 4; i++)
array_score[i] = (int *)malloc(4 * sizeof(int));
//--
for(i = 0; i < 4; i++)
{
printf("Please enter the student_%d four grades, (separated with a space )\n", i+1);
int ret = scanf("%d %d %d %d", (*(array_score + i) + 0), (*(array_score + i) + 1),
(*(array_score + i) + 2), (*(array_score + i) + 3));
fflush(stdin);
if(4 != ret)
i--;
}
//There is something wrong with the function return value
float ave_score = average_score(array_score);
//--
int low_score = lowest_score(array_score);
//The output
printf("average score: %d\n lowest score: %d\n", ave_score, low_score);
return 0;
}
This allocates space for 4 pointers and then writes 5, since i takes on the values 0, 1, 2, 3 and 4:
array_score = (int **) malloc(4 * sizeof(int *));
for(i = 0; i <= 4; i++)
array_score[i] = (int *)malloc(4 * sizeof(int));
Note that in C you shouldn't cast the return from malloc. There's an answer on Stackoverflow telling all the details why this is not helpful.