makes pointer(integer) from integer(pointer) without a cast - c

#include<stdio.h>
#include<stdlib.h>
int **transpose(int a[], int b[], int raw, int column){
int i, j;
for(i=0; i < raw ; i++)
for(j=0; j < column ; j++)
*(b+(j*raw + i)) = *(a+(i*column + j));
return *b;
}
int **mk_matrix(int raw, int col){
int i;
int **matrix = (int**)malloc(sizeof(int*)*raw);
matrix[0] = (int*)malloc(sizeof(int)*(raw*col));
for(i=1 ; i < raw ; i++)
matrix[i] = matrix[i-1] + col;
return matrix;
}
void main(void){
int r, c, i, j;
printf("Input the size of matrix : ");
scanf("%d %d", &r, &c);
int **matrix = mk_matrix(r, c);
int **trans_matrix = mk_matrix(c, r);
printf("Input elements of the %dx%d matrix : ", r, c);
for(i=0; i < r ; i++)
for(j=0; j < c ; j++)
scanf("%d", &matrix[i][j]);
**trans_matrix = transpose(matrix[0], trans_matrix[0], r, c);
for(i=0; i < c ; i++){
for(j=0; j < r ; j++)
printf("%d ", trans_matrix[i][j]);
printf("\n");
}
}
In dev c++, this code runs correctly by I wanted but it comes
return makes pointer from integer without a cast -> return *b;
assignment makes integer from pointer without a cast -> **trans_matrix = transpose(matrix[0], trans_matrix[0], r, c);
warnings.
How can i fix my code not showing warnings?

Well you don't need to
return *b
int **transpose(int a[], int b[], int raw, int column)
just modify above to
void transpose(int a[], int b[], int raw, int column){
int i, j;
for(i=0; i < raw ; i++)
for(j=0; j < column ; j++)
*(b+(j*raw + i)) = *(a+(i*column + j));
}
and in main function
**trans_matrix = transpose(matrix[0], trans_matrix[0], r, c);
to
transpose(matrix[0], trans_matrix[0], r, c);
as transpose function is already performing necessary changes to trans_matrix. You do not need to return.
this will resolve warning issue.

In the function transpose() you are returning a ptr to int when the return type of transpose() is ptr to ptr to int. Now because you are returning the value of the wrong (not expected) data type, you are getting your second warning.
Another thing is when you are working with addresses of the matrices in the transpose() function you don't need to return any kind of value because ultimately you are changing values that are stored on that address. You are not working on a copy of that value. That's why you don't need to:
**trans_matrix = transpose(matrix[0], trans_matrix[0], r, c);
I don't know why you are overcomplicating the functions. You can write them as:
int transpose(int **a, int **b, int row, int column)
{
int i, j;
for(i=0; i < column ; i++)
for(j=0; j < row ; j++)
b[i][j] = a[j][i];
return 0;
}
and
int **mk_matrix(int row, int col)
{
int i;
int **matrix = malloc(sizeof(int*)*row);
for(i=0; i<row; i++)
matrix[i] = malloc(sizeof(int)*(col));
return matrix;
}
and in main() you just need to modify how you call the transpose() method:
transpose(matrix, trans_matrix, r, c);
P.S. Also, check if the memory space you are requesting(malloc()) is allocated to the ptr or not.

Related

Function inputElements() taking input only once

I am trying to create a program to find the transpose of a matrix my dynamic memory allocation. However, while entering the elements of the matrix I can't input more than one element, its only taking the a[0][0] as the input and the program is ending after that.
#include <stdio.h>
#include <stdlib.h>
void createMatrix(int **, int, int);
void inputElements(int **, int, int);
void transpose(int **, int **, int, int);
void display(int **, int, int);
void main()
{
int **matrix, **trans, rows, cols;
printf("\nEnter number of rows in the matrix: ");
scanf("%d", &rows);
printf("\nEnter number of columns in the matrix: ");
scanf("%d", &cols);
createMatrix(matrix, rows, cols);
createMatrix(trans, cols, rows);
inputElements(matrix, rows, cols);
transpose(matrix, trans, rows, cols);
printf("\nMATRIX:\n");
display(matrix, rows, cols);
printf("\nTRANSPOSE OF THE MATRIX:\n");
display(trans, rows, cols);
}
void createMatrix(int **a, int r, int c) //for allocating memory for the matrix
{
int i, j;
a = (int **)malloc(sizeof(int *) * r);
for(i = 0; i < r; i++)
a[i] = (int *)malloc(sizeof(int) * c);
}
void inputElements(int **a, int r, int c) //for entering matrix elements
{
int i, j, t;
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
printf("\nEnter matrix element[%d][%d]: ", i + 1, j + 1);
fflush(stdin);
getchar();
scanf("%d", &(a[i][j]));
}
}
}
void transpose(int **a, int **t, int r, int c) //for finding out the transpose of the matrix
{
int i, j;
for (i = 0; i < c; i++)
{
for (j = 0; j < r; j++)
t[i][j] = a[j][i];
}
}
void display(int **a, int r, int c) //for displaying the matrix
{
int i, j;
for (i = 0; i < r; i++)
{
printf("\n");
for (j = 0; j < c; j++)
printf("\t%d", a[i][j]);
}
}
There are many posts about scanf in loops I've seen, but I wasn't able to connect my issue with any of them.

Error when passing 2D array to function in c

I am writing a program to calculate matrix multiplication but it does not work. When I debug and check each value of the array a and b in function printMatrixMultiplication (which are entered by user), GDB prints out "cannot perform pointer math on incomplete type try casting". (I have searched for it but I still don't get it.) The function only works when the input is predefined in main.
This is my code
#include <stdio.h>
void input(int m, int n, double a[m][n]);
void output(int m, int n, double a[m][n]);
void printMatrixMultiplication(int row_a, int col_a, double a[row_a][col_a], int row_b, int col_b, double b[row_b][col_b]);
int main()
{
int row_a, col_a, row_b, col_b;
// get value of matrix a
printf("row_a = ");
scanf("%d", &row_a);
printf("col_a = ");
scanf("%d", &col_a);
double a[row_a][col_a];
input(row_a, col_a, a);
// output(row_a, col_a, a);
// get value of matrix b
printf("row_b = ");
scanf("%d", &row_b);
printf("col_b = ");
scanf("%d", &col_b);
double b[row_b][col_b];
input(row_b, col_b, a);
// output(row_b, col_b, a);
printMatrixMultiplication(row_a, col_a, a, row_b, col_b, b);
//test
// double a[2][2]={1,2,3,4};
// double b[2][3]={1,2,3,4,5,6};
// printMatrixMultiplication(2,2,a,2,3,b);
return 0;
}
void input(int m, int n, double a[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
scanf("%lf", &a[i][j]);
}
}
}
void output(int m, int n, double a[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%.2f ", a[i][j]);
}
printf("\n");
}
}
void printMatrixMultiplication(int row_a, int col_a, double a[row_a][col_a], int row_b, int col_b, double b[row_b][col_b])
{
if (col_a != row_b)
{
return;
}
double res[row_a][col_b]; //this matrix store results
for (int i = 0; i < row_a; i++) //the values be stored line by line, this
{ //operation is controled by i and j loops.
for (int j = 0; j < col_b; j++) //the k loop helps calculate dot_product.
{
double dot_product = 0;
for (int k = 0; k < col_a; k++)
{
dot_product += a[i][k] * b[k][j]; //ERROR HERE
}
res[i][j] = dot_product;
}
}
output(row_a, col_b, res);
}
So, where does the error come from and how to fix it?
Irrelevant, but the function is not well implemented so if possible, I would really appreciate if anyone gives me a hint to improve it.
I am using GCC version 6.3.0.
It's typo in your code when reading matrix b.
Just replace:
input(row_b, col_b, a);
with
input(row_b, col_b, b);

i have problem with acessing 2d array via function

i am learning pointers and i write these code to add two martix via function, it compile well and give correct answer for 2x2 matrix but for more than two row and col it fails when i try it with 3x3 matrix [0][0] element for the first matrix it automaticaly become 6 and [1][0] it became 9 every time, i can't figure out why this happen
#include <stdio.h>
//-----------------Function------------------
void add(int (*p1)[10], int (*p2)[10], int (*p3)[10], int r, int c);
void get(int (*p1)[10], int r, int c);
void print(int (*p1)[10], int r, int c);
//---------------Main Program----------------
int main()
{
//declartion
int i, j, r, c;
printf("\n\tenter the row and column of matrix\n\t");
scanf("%d %d", &r, &c);
int m1[r][c], m2[r][c], m3[r][c];
printf("\n\tenter the element of first matrix\n\t");
get(m1, r, c);
print(m1, r, c);
printf("\n\tenter the element of second matrix\n\t");
get(m2, r, c);
print(m2, r, c);
add(m1, m2, m3, r, c);
printf("\n");
print(m3, r, c);
return(0);
}
//-------------Define Function---------------
//get()
void get(int (*p1)[10], int r, int c)
{
int i, j;
for(i = 0; i < r; i++)
{
printf("\n\t");
for(j = 0; j < c; j++)
{
scanf("%d", (*(p1+i)+j));
}
}
}
//--------------------X----------------------
//add()
void add(int (*p1)[10], int (*p2)[10], int (*p3)[10], int r, int c)
{
int i, j;
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
//printf("\n%d %d = %d & %d", i, j, *(*(p1+i)+j), *(*(p2+i)+j));
*(*(p3+i)+j) = *(*(p1+i)+j) + *(*(p2+i)+j);
}
}
}
//--------------------X----------------------
//print()
void print(int (*p1)[10], int r, int c)
{
int i, j;
for(i = 0; i < r; i++)
{
printf("\n");
for (j = 0; j < c; j++)
{
printf("\t%d", *(*(p1+i)+j));
}
}
}
//--------------------X----------------------
Drop the array pointer notation and the fixed size. Use variable-length arrays based on the parameters.
Remove useless comments like // get ... void get...
Don't use unreadable de-referncing with *(arr+i) when you could be writing readable arr[i].
Print new line after each row, not before each row.
Here's a cleaned up program which compiles. I haven't tested it.
#include <stdio.h>
void add (int r, int c, int p1[r][c], int p2[r][c], int p3[r][c]);
void get (int r, int c, int p1[r][c]);
void print (int r, int c, int p1[r][c]);
int main (void)
{
int i, j, r, c;
printf("\n\tenter the row and column of matrix\n\t");
scanf("%d %d", &r, &c);
int m1[r][c], m2[r][c], m3[r][c];
printf("\n\tenter the element of first matrix\n\t");
get(r, c, m1);
print(r, c, m1);
printf("\n\tenter the element of second matrix\n\t");
get(r, c, m2);
print(r, c, m2);
add(r, c, m1, m2, m3);
printf("\n");
print(r, c, m3);
return(0);
}
void get (int r, int c, int p1[r][c])
{
for(int i = 0; i < r; i++)
{
for(int j = 0; j < c; j++)
{
scanf("%d", &p1[i][j]);
}
}
}
void add (int r, int c, int p1[r][c], int p2[r][c], int p3[r][c])
{
for(int i = 0; i < r; i++)
{
for(int j = 0; j < c; j++)
{
p3[i][j] = p1[i][j] + p2[i][j];
}
}
}
void print (int r, int c, int p1[r][c])
{
for(int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
printf("\t%d", p1[i][j]);
}
printf("\n");
}
}

Adding 2 matrices using pointers

I can acheive it by passing (c,a,b) to add_mat function, where result of a,b is stored in c like,
void add_mat(int c[][3], int a[][3], int b[][3], int m, int n)
What should be the return type of add_mat if I want to construct the funtion in this way
?? add_mat(int a[][3], int b[][3], int m, int n)
Below is a sample code
#include<stdio.h>
void read_mat(int a[][3], int m, int n){
//scan data
for(int i=0; i<m; i++){
for(int j=0; j<n; j++){
printf("[%d][%d] : ",i,j);
a[i][j]=i+j;
}
}
}
int* add_mat(int a[][3], int b[][3], int m, int n){
int c[3][3];
for(int i=0; i<m; i++){
for(int j=0; j<n; j++){
c[i][j]=a[i][j]+b[i][j];
}
}
return c;
}
int main(){
int a[3][3];
int m=2,n=2; //mxn of a matrix
read_mat(a, m, n);
//add
int b[3][3];
read_mat(b, m, n);
int* c[3][3];
c = add_mat(a,b,m,n);
return 0;
}
Like passing or pointing the calculated value c inside add_mat function to variable in main function.
You cannot do that, since the memory of the c matrix will be gone when the function terminates.
You need to dynamically allocate it with malloc(), in order for the memory not to be free'd, unless you call free(). I have some examples for that in 2D dynamic array (C), if you want to take a look.
With your previous function, you would create the matrix c outside the function (in main()), that's why dynamic memory allocation was not required.
PS: You should compile with warnings enabled:
prog.c: In function 'add_mat':
prog.c:19:12: warning: returning 'int (*)[3]' from a function with incompatible return type 'int *' [-Wincompatible-pointer-types]
return c;
^
prog.c:19:12: warning: function returns address of local variable [-Wreturn-local-addr]
prog.c: In function 'main':
prog.c:32:7: error: assignment to expression with array type
c = add_mat(a,b,m,n);
^
prog.c:31:10: warning: variable 'c' set but not used [-Wunused-but-set-variable]
int* c[3][3];
^
Here is a working example, which is just for demonstrative purposes:
#include <stdio.h>
#include <stdlib.h>
void read_mat(int a[][2], int n, int m){
//scan data
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
a[i][j] = i + j ;
}
}
}
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;
}
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** add_mat(int a[][2], int b[][2], int m, int n){
int** c = get(n, m);
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
c[i][j]=a[i][j]+b[i][j];
}
}
return c;
}
int main(){
int n = 2, m = 2; //nxm of a matrix
int a[n][m];
read_mat(a, n, m);
//add
int b[n][m];
read_mat(b, n, m);
int** c;
c = add_mat(a, b, n, m);
print(c, n, m);
free2Darray(c ,n);
return 0;
}
Output:
array[0][0] = 0
array[0][1] = 2
array[1][0] = 2
array[1][1] = 4
PPS: If you really want to use static arrays, then I recommend using int c[3][3]; add_mat(c, a, b, m, n);
Oh yes, the pointers ...
In C, locally declared arrays usually are allocated on the stack (not on the heap) which means they are not valid outside the respective scope.
In other words, in your function add_mat(), c technically can be returned, but the address it points to will only contain meaningful matrix data as long as the function is executed.
After having returned from the function, the return value of the function is a pointer which still contains (points to) the address where the matrix was stored during execution of the function, but the contents of that location, i.e. the matrix data, can contain arbitrary garbage now.
So what you are doing is technically possible (i.e. throws no compile errors), but is definitely not what you want.
Secondly, your line int* c[3][3]; probably is not what you intend it to be. You are declaring c to be a two-dimensional array (matrix) of pointer to int here. This is not correct since you want to process int values, but not pointers to int values (which are addresses).
To solve both problems, just write int c[3][3]; instead of int* c[3][3]; and change your add_mat() function as follows:
void add_mat(int a[][3], int b[][3], int c[][3], int m, int n){
for(int i=0; i<m; i++){
for(int j=0; j<n; j++){
c[i][j]=a[i][j]+b[i][j];
}
}
}
Then call that function like that:
add_mat(a,b,c,m,n);
In your code add_mat returns the pointer to the variable which lives while the function executes only. You can accomplish your goal with dynamically allocated matrix.
In C it is common to pass a dynamically allocated matrix via pointer to pointers to the rows of matrix as a first parameter:
void foo(int** matrix, size_t m, size_t n);
Here matrix is a pointer to the array of pointers. Every pointer in this array points to the row of matrix. So, matrix[0] points to the array containing the first row of matrix.
And it is common to use size_t type for any sizes of arrays.
If you need create matrix dynamically, be careful with memory. Every dynamically allocated block should be released. Otherwise you will get memory leaks, that may cause the program crash. Therefore, when you allocate rows of matrix, you should check if allocation of current row was successfull. If not, you should release all previously allocated rows.
There is a working code for your question:
#include <stdio.h>
#include <stddef.h>
#include <malloc.h>
void free_mat(int** a, size_t m) {
if (!a) {
return;
}
for (size_t i = 0; i < m; ++i) {
free(a[i]);
}
free(a);
}
int** create_mat(size_t m, size_t n) {
int** rows = calloc(m, sizeof(int*));
if (!rows) {
return NULL;
}
for (size_t i = 0; i < m; i++) {
rows[i] = malloc(n * sizeof(int));
if (!rows[i]) {
free_mat(rows, m);
return NULL;
}
}
return rows;
}
void read_mat(int** a, size_t m, size_t n) {
for (size_t i = 0; i < m; i++) {
for (size_t j = 0; j < n; j++) {
printf("[%d][%d]: ", i, j);
scanf("%d", a[i] + j);
}
}
}
void print_mat(const int* const* a, size_t m, size_t n) {
for (size_t i = 0; i < m; ++i) {
for (size_t j = 0; j < n; ++j) {
printf("[%d][%d]: %d\n", i, j, a[i][j]);
}
}
}
int** add_mat(const int* const* a, const int* const* b, size_t m, size_t n) {
int** c = create_mat(m, n);
if (c) {
for (size_t i = 0; i < m; ++i) {
for (size_t j = 0; j < n; ++j) {
c[i][j] = a[i][j] + b[i][j];
}
}
}
return c;
}
int main() {
size_t m = 3;
size_t n = 3;
int** a = create_mat(m, n);
int** b = create_mat(m, n);
if (!a || !b) {
printf("error when allocating matrix\n");
}
else {
read_mat(a, m, n);
read_mat(b, m, n);
int** c = add_mat(a, b, m, n);
if (!c) {
printf("error when allocating matrix\n");
}
else {
print_mat(c, m, n);
free_mat(c, m);
}
}
free_mat(a, m);
free_mat(b, m);
return 0;
}
But you would be more flexible, if add_mat didn't create a new matrix.
It is common to pass a pointer to the result matrix as a function parameter:
void add_mat(int** c, const int* const* a, const int* const* b, size_t m, size_t n);

Using scanf() with a pointer to a double pointer

I feel like I've attempted every combination I know of to get this to work and can't figure it out. How can I scanf() into an int** passed as a pointer to a function? I tried searching but couldn't find this, if it's a duplicate please let me know and I'll delete. It begins to run and after entering a few values it segfaults.
Here's my code, I think it's messing up on the scanf() line of the setMatrix() function:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int ***mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", mat[i][j]); // problem here??
printf("matrix[%d][%d]: %d\n", i, j, (*mat)[i][j]);
}
}
return;
}
// print matrix
void printMatrix(int ***mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", (*mat)[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(&mat, r, c);
printMatrix(&mat, r, c);
}
There is no need to use triple pointer ***. Passing two-dimensional array will work as is. Here is the code:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int **mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", &mat[i][j]); // no problem here
printf("matrix[%d][%d]: %d\n", i, j, mat[i][j]);
}
}
}
// print matrix
void printMatrix(int **mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(mat, r, c);
printMatrix(mat, r, c);
}
Should be:
scanf("%d", &(*mat)[i][j]);
You're passing a pointer to you matrix object, so you need to dereference it (with *) just as you do with printf. scanf then needs the address of the element to write into, so you need the &

Resources