I have a matrix in C and I want to create another one which has double rows than the first matrix.Those added rows I want to have the values of first matrix ,but with changed sign. I am trying to understand dynamic allocation,and I don't understand where I am wrong. The error that compiler says is that:"invalid conversion from void* to int*" . Here is my code:
#include <stdio.h>
#include<conio.h>
#include<stdlib.h>
int *extend_matrix=NULL;
int *matrix=NULL;
int *negative_matrix=NULL;
int main(void)
{
int i,j,m,n;
printf("Enter the number of rows and columns of matrix\n");
scanf("%d%d", &m, &n);
int *matrix = (int *)malloc(m * n * sizeof(int));
int *negative_matrix=(int*)malloc(m*n*sizeof(int));
printf("Enter the elements of first matrix\n");
for ( i = 0 ; i < m ; i++ )
for ( j = 0 ; j < n ; j++ )
scanf("%d", &matrix[i][j]);
for(i = 0 ; i < m ; i++)
for(j = 0 ; j < n ; j++)
printf("the matrix is: \n",matrix[i][j]);
negative_matrix=-matrix[i][j];
for(i=0;i<m+m;i++)
extend_matrix[i]=realloc(matrix[i],sizeof(int)*(m+m));
for(j=0;j<n;j++)
extend_matrix[j]=realloc(matrix[j],sizeof(int)*n);
extend_matrix[i][j]=matrix[i][j]+negative_matrix[i][j];//how to concatenate them?
getch();
return 0;
}
Seems you're a little confused. Let me to write a short example code
EDIT:
Ok, go here
There you'll find my example. I've not completed it, but just gave an input on how to finish it.
Note this, too:
From 66 to 68 line we have this code:
for (i = 0; i < rows; i++){
free(first_matrix[i]);
}
This is because each elements of our matrix is a pointer and all them point to an array allocated on the heap. So, if you just freed first_matrix, like this:
free(first_matrix);
you would have freed only first_matrix from its own content on the heap (and not that one of each its element)
Related
I tried implemented matrix struct in C, ( generate and show that ). I don't have a trouble with generate but i discovered something I didn't understand. When i uncomment printf("\n") i don't get variable from matrix but whith commented printf("\n") everything working correct. It's not a big problem but I'm curious why this happen. It's looks like printf has destructed my structure.
void show_matrix(struct matrix matrix1){
for(int i =0; i < matrix1.number_of_row; i++){
for(int j = 0; j <matrix1.number_of_columns; j++){
printf("%d " , matrix1.variable[i * matrix1.number_of_columns + j]);
}
// printf("\n");
}
}
Here is my main :
#include <stdio.h>
#include "matrix_operations.h"
int main(){
int columns;
int rows;
printf("Enter the number of columns \n");
scanf("%d",&columns);
printf("Enter the number of rows \n");
scanf("%d", &rows);
struct matrix matrix1;
matrix1 = generate_matrix(columns,rows);
show_matrix(matrix1);
return 0;
}
Here is my file matrix_operations.h :
#include "matrix.h"
#include <stdlib.h>
struct matrix generate_matrix(int columns, int rows){
int value;
struct matrix matrix1;
matrix1.number_of_columns = columns;
matrix1.number_of_row = rows;
int values[rows * columns];
matrix1.variable = values;
for(int i = 0 ; i < rows ; i++){
for(int j =0 ; j <columns ; j++){
value = random() %2;
matrix1.variable[i * columns +j] = value;
/* Uncomment to see generated matrix
printf("%d ", matrix1.values[ i * columns +j]);
*/
}
/* Uncomment to see generated matrix
printf("\n");
*/
}
return matrix1;
}
void show_matrix(struct matrix matrix1){
for(int i =0; i < matrix1.number_of_row; i++){
for(int j = 0; j <matrix1.number_of_columns; j++){
printf("%d " , matrix1.variable[i * matrix1.number_of_columns + j]);
}
/* Uncomment to not working correctly
printf("\n");
*/
}
}
Here is my struct in file matrix.h :
struct matrix{
int number_of_columns;
int number_of_row;
int *variable;
};
Sample input :
4
4
Sample output with commented printf (16 random numbers 0 or 1):
1 0 1 1 0 0 1 1 0 0 1 1 0 1 0 1
Sample output with uncommented printf
1 0 1 1
-2051332800 32571 0 0
0 0 -2053095405 32571
-2051684704 32571 10 0
The problem is that generate_matrix returns a struct matrix with a variable field that points at a local variable (values) of the function. This goes out of scope when the function returns, leaving you with a dangling pointer, and when you later dereference it, you get undefined behavior.
You need to ensure that this pointer points at something with sufficient lifetime to not become dangling. One way to do that would be to use malloc in the generate_matrix function rather than using a local variable:
int *values = malloc(rows * columns * sizeof(int));
This will allocate memory that lasts until you explicitly free it. Now you have the issue that you need to figure out when to free it (when you no longer need it), or you'll have a memory leak.
Part of my assignment is to sort a 2D array into ascending order, and I cannot figure out how to do it for the life of me.
What I have so far:
int Sort2DArray(int A[][COL], unsigned int rowsize, unsigned int colsize)
{
int i, j, k, temp;
for (i=0; i<rowsize-1; i++){
for (k=0; k<colsize; k++){
for (j=0; j<rowsize-1; j++){
do {
temp = A[k][j];
A[k][j] = A[k][j+1];
A[k][j+1] = temp;
} while (A[k][j]>A[k][j+1]);
}
}
}
}
This will take an array this and return:
3 2 1 1 2 3
5 8 7 ---->>> 5 7 8
4 9 3 3 4 9
However, I need it to return:
1 2 3
4 5 6
7 8 9
So, is there any way you guys can help me? Thanks!
EDIT:
#include <stdio.h>
#include <stdlib.h>
#define COL 20
#define ROW 20
void PopulateArray2DUnique (int [][COL], unsigned int, unsigned int, int, int);
void DisplayArray2D(int [][COL], unsigned int, unsigned int);
int FindLargest(int [][COL], unsigned int, unsigned int);
int FindColSum(int [][COL], unsigned int, unsigned int, unsigned int);
int Sort2DArray(int [][COL], unsigned int, unsigned int);
int main()
{
int A[ROW][COL];
int min=1, max=99;
unsigned int rowsize, colsize, col_to_sum;
printf ("Input your desired row and column size: \n");
scanf ("%u%u", &colsize, &rowsize);
PopulateArray2DUnique(A, rowsize, colsize, min, max);
DisplayArray2D(A, rowsize, colsize);
FindLargest(A, rowsize, colsize);
printf ("Which column would you like to find sum of?\n");
scanf ("%d", &col_to_sum);
FindColSum(A, rowsize, colsize, col_to_sum);
Sort2DArray(A, rowsize, colsize);
DisplayArray2D(A, rowsize, colsize);
return 0;
}
Is it possible?
Yes, it's possible. The most important thing to understand is that your sort routine, and all of the basic sort routines you see in examples, generally sort a 1D array.[1] The same routine can be used to sequentially sort a 2D array as you are attempting to do, but you have to recognize you want to pass your 2D array to the sort function as a pointer-to-type (simple 1D array, e.g. 'int *'), rather than as a pointer-to-array of X elements (your 2D array, e.g. 'int (*)[NCOLS]')
The key to passing the array is to simply pass the address to the first element in your array. Regardless of whether you declared it as a 1D or 2D array (1) that is the address where the values begin in memory; and (2) all array values are sequential. Meaning that you can address every value in a 1D or 2D array by start_address + offset.
Take for example your simple bubble-sort routine:
void bubblesort (int *a, size_t n)
{
size_t i, j;
int temp;
for (i = 0; i < n; i++) {
for (j = 0; j < (n-1); j++) {
if (a[j] > a[j + 1]) {
temp = a[j + 1];
a[j + 1] = a[j];
a[j] = temp;
}
}
}
}
If you had declared a 2D array (e.g. int array[][NCOL];, not pointer-to-pointer-to-type int **array;) that you wished to sequentially sort, you could call your sort routine by simply passing the start address as follows:
bubblesort (*array, nelem);
or
bubblesort (&array[0][0], nelem);
(both are equivalent, with 'nelem' being the total number of elements)
If you attempt to declare your sort function by passing a pointer to array (e.g. bubblesort (int (*array)[NCOL], size_t n); you will run difficulty immediately attempting to loop over the indexes because using the traditional nested loop layout, there is no easy way to compare array[i][j] with array[i+1][0], etc..
The following is a short example putting it all together. Look it over and let me know if you have questions:
#include <stdio.h>
#include <stdlib.h>
#define NCOL 3
void bubblesort (int *a, size_t n);
int main ()
{
int array[][NCOL] = {{3,2,1},
{5,8,7},
{4,9,3}};
int i, j, nrows, nelem;
nrows = sizeof array/sizeof *array;
nelem = sizeof array/sizeof **array;
printf ("\noriginal:\n\n");
for (i = 0; i < nrows; i++) {
for (j = 0; j < NCOL; j++)
printf (" %2d", array[i][j]);
putchar ('\n');
}
bubblesort (*array, nelem);
printf ("\nsorted:\n\n");
for (i = 0; i < nrows; i++) {
for (j = 0; j < NCOL; j++)
printf (" %2d", array[i][j]);
putchar ('\n');
}
return 0;
}
void bubblesort (int *a, size_t n)
{
size_t i, j;
int temp;
for (i = 0; i < n; i++) {
for (j = 0; j < (n-1); j++) {
if (a[j] > a[j + 1]) {
temp = a[j + 1];
a[j + 1] = a[j];
a[j] = temp;
}
}
}
}
Output
$ ./bin/qsort_2d_linear
original:
3 2 1
5 8 7
4 9 3
sorted:
1 2 3
3 4 5
7 8 9
Note: you can do the same thing with qsort rather easily with the standard integer compare function and calling qsort (array, nelem, sizeof **array, icompare);
footnote[1]: all arrays in C are 1D arrays, the 2D array is simply addressed in a way to allow 2D indexing. It is still a sequential block of 'type' values in memory.)
I'm not sure if I have the best method here, however what I would do, is store each value from the array into one large 1D array, sort that and then assign them to the 2D array.
int Sort2DArray(int A[][COL], unsigned int rowsize, unsigned int colsize)
{
int arraySize = rowsize * colsize;
int sortingArray[arraySize];
int i = 0, row, col, temp, prevPos;
//Fills the sortingArray with all the values in the 2D array
for (col = 0; col < colsize; ++col) {
for (row = 0; row < rowsize; ++row) {
sortingArray[i] = A[row][col];
++i;
}
}
//Sorts the 1D array (Insertion Sort)
for (i = 1; i < arraySize; ++i)
{
temp = sortingArray[i];
prevPos = i - 1;
while (j >= 0 && sortingArray[prevPos] > temp)
{
sortingArray[prevPos+1] = sortingArray[prevPos];
prevPos = prevPos - 1;
}
sortingArray[prevPos + 1] = temp;
}
//Writes data back into 2D array
i = 0;
for (row = 0; row < rowsize; ++row) {
for (col = 0; col < colsize; ++col) {
A[row][col] = sortingArray[i];
++i;
}
}
}
I hope I didn't get too confusing with all those dimensions, but you get the idea. If you spot anything incorrect, let me know.
It smells like homework to me, thus, I will only help you a little, and leave the rest to yourself.
When I was very new to C, and my first programming language, I had solved a lot of problems, and one of them was this.
The code I am pasting here is taken from here, a website, which I used to use a lot.
It is up to you to understand the algorithm, and program, and use it in your program.
#include<stdio.h>
int main( )
{
int a[][6]={
{25,64,96,32,78,27}, //Desired solution : {25,27,32,64,78,96},
{50,12,69,78,32,92} // {50,92,78,12,32,69}
};
int i, j, k, temp, temp1 ;
//Bubble sorting is applieed on one first row while the other row is swapped
for(j=1;j<6;j++)
{
for(i=0; i<5; i++)
{
if(a[0][i]>a[0][i+1])
{
temp=a[0][i];
a[0][i]=a[0][i+1];
a[0][i+1]=temp;
temp1 = a[1][i];
a[1][i] = a[1][i+1];
a[1][i+1]=temp1;
}
}
}
printf ( "\n\nArray after sorting:\n") ;
for ( i = 0 ; i <2; i++ )
{
for(j=0; j<6; j++)
{
printf ( "%d\t", a[i][j] ) ; //printing sorted array
}
printf("\n");
}
}
It is a bit different from the code on the site, as I used to always used to work in Ubuntu, and linux never had conio.h. Also, if you are angry for me only providing the code used everywhere, and not doing all your work, keep in mind that homework assignments are for making the student think, and if I spoon-feed you, the purpose will be lost.
NOTE: Always post your full code which can be compiled successfully, as the code you have posted does not compile, as you have not declared all your functions. Thus, it is very difficult to understand you code.
Also, do not try to fool us, as the input you have mentioned does not have a 6, and you want a 6 also to be returned so actually even you have not compiled your code.
I have to be losing my mind here. I'm getting a segfault at the line for(i = 0; i < N; i++) {. I've never encountered anything like this. Here's the full code:
#include <stdio.h>
#include <time.h>
#define N 2400
#define M 2000
#define P 500
int main() {
int a[N][N];
int b[N][N];
int c[N][N];
int i, j;
// Initialize matrix A
for(i = 0; i < N; i++) {
for(j = 0; j < M; j++) {
a[i][j] = j-1+2;
}
}
// Initialize matrix B
for(i = 0; i < M; i++) {
for(j = 0; j < P; j++) {
b[i][j] = i-j+1;
}
}
}
First : you have declared a, b and c as [N][N] matrix, but you initialize them as if they were [N][M] and [M][P] matrix. Considering N > M > P, that should not cause a segfault, but the intent is not clear.
Second, if you replace your defines by :
#define N 10
#define M 5
#define P 2
Your program work. This is because local variables a and b are stored on the stack and your stack is limited in size. Consult your compiler and your system documentation to know exactly the limits imposed.
To avoid such problem, allocate your memory using malloc or equivalent function, that allocate memory on the heap, which is less constrained.
This question already has answers here:
How do I work with dynamic multi-dimensional arrays in C?
(9 answers)
Closed 8 years ago.
This is my code. My purpose is to allocate memory to a 2D array at run time upto whatever size is given in input.
Why is segmentation fault occuring? Is it because array elements have to be stored consecutively and malloc(dynamic allocation) is not letting this happen?
OR I am doing some error in writing this code. Please guide me through.
Thanks in advance.
int main(){
// STEP 1
int size,**arr,i=0,j=0;
printf("Enter the size of matrix : ");
scanf("%d",&size);
// STEP 2
arr = (int**)malloc(size*size*sizeof(int));
printf("\n Enter the %d elements : \n",size*size);
for(i=0;i<size;i++){
for(j=0;j<size;j++){
// STEP 3
scanf("%d",&arr[i][j]);
}
}
/*
for(i=0;i<size;i++){
for(j=0;j<size;j++){
printf("%d\n",matrix[i][j]);
}
}
*/
return 0;
}
This is a classic mistake.
A pointer to pointers is actually not the same as a two-dimensional array.
Granted, you can access elements of both via the var[x][y] syntax, but the memory layout of
int foo[x][y]
is different from
int **bar
If you really want to have this dynamic, you will have to allocate space for your list of pointers, then allocate space for your elements to each pointer in turn.
bar = malloc( x * sizeof(int*) );
for ( int i = 0 ; i < x ; i++ )
bar[i] = malloc( y * sizeof(int) );
If at all possible, you should try and avoid this in favor of an actual two-dimensional array, which as of C99 you can declare on the stack even if its size is determined at runtime:
int main()
{
int n;
scanf("%d", &n);
int array[n][n];
// ...
return 0;
}
You should allocate like this:
arr = malloc(size * sizeof(int*));
for (int i = 0; i <size; i++)
arr[i] = malloc(size * sizeof(int));
And do not forget to free the memeory using free.
Side Note: Do not cast the return value of malloc.
One idea that would work and would also get you rid of the memory fragmentation induced by this double pointers level allocation is make your matrix linear:
arr = (int*) malloc (size*size*sizeof(int));
And then simply access your elements with arr[i*size + j] instead of arr[i][j]:
use it like this : a perfect example of dynamic memory Allocation
void mxmult()
{
int n,m,a,b,c,d, sum=0;
int x,y,z;
printf("Enter first order [n*n]\n");
scanf("%d", &n);
printf("Enter second order [m*m]\n");
scanf("%d", &m);
if (n!=m)
{
printf("Invalid orders");
}
else
{
//mem allocate for matrix 1
int **mat1 = (int**)malloc(n*sizeof(int));
for(x=0;x<n;x++)
{
mat1[x]=(int*)malloc(n*sizeof(int));
}
// input matrix 1
printf("Enter the first matrix entries\n");
for (a = 0; a <n; a++)
{
for (b = 0; b < n; b++)
{
scanf("%d", &mat1[a][b]);
}
}
// memory allocate matrix 2
int **mat2 = (int**)malloc(m*sizeof(int));
for(y=0;y<n;y++)
{
mat2[y]=(int*)malloc(m*sizeof(int));
}
//inpur matrix 2
printf("Enter the second matrix entries\n");
for (c = 0; c <n; c++)
{
for (d= 0; d < n; d++)
{
scanf("%d", &mat2[c][d]);
}
}
//Memory allocate matrix Mult
int **mult=(int**)malloc(m*sizeof(int));
for(z=0;z<m;z++)
mult[z]=(int*)malloc(m*sizeof(int));
for (a = 0; a < n; a++)
{
for (d = 0; d < m; d++)
{
for (c = 0; c < n; c++)
{
sum=sum + (mat1[a][c] *mat2[c][d]);
}
mult[a][d] = sum;
sum= 0;
}
}
printf("Product\n");
for ( a = 0 ; a < n ; a++ )
{
for ( d = 0 ; d < m ; d++)
printf("%d\t", mult[a][d]);
printf("\n");
}
}
}
I want to change rows into column and column into rows of that 2-D array
I want a program which takes input and gives output as below.
Input: 1 2 3
4 5 6
Output: 1 4
2 5
3 6
Input: 1 2 3
4 5 6
7 8 9
Output: 1 4 7
2 5 8
3 6 9
I did a sample which in hardcoded array as below
int main()
{
int i,j;
int grades[2][3] = { {55, 60, 65},
{85, 90, 95}
};
for( j = 0; j < 3; j++)
{
for( i = 0; i < 2;i++)
{
printf("%d\t",grades[i][j]);
}
printf("\n");
}
return 0;
}
Its long time since i programmed in C , is there anyway we can make things dynamic or better way of doing the same. Right now its hardcoded.
I remember we have to use malloc or so , is that right.
psuedo code is also fine.
Taking from Zhehao Mao user and fixing it, the would look like this:
#include <stdio.h>
void transpose(int *src, int *dest, int rows, int cols){
int i,j;
for(i=0; i<rows; i++){
for(j=0; j<cols; j++){
dest[j*rows + i] = src[i*cols + j];
}
}
}
int main(void)
{
int oldar[2][3] = {{1,2,3},{4,5,6}};
int newar[3][2];
transpose(&oldar[0][0], &newar[0][0], 2, 3);
int i, j;
for(i = 0; i < 2; i++)
{
for(j = 0; j < 3; j++)
printf("%d ", oldar[i][j]);
printf("\n");
}
for(i = 0; i < 3; i++)
{
for(j = 0; j < 2; j++)
printf("%d ", newar[i][j]);
printf("\n");
}
}
The reason the original post can't work is that int ** expects a pointer to pointers like:
int **a ---------> int *int1 --> 1
int *int2 --> 2
int *int3 --> 3
which is not what we get when we say int a[n][m]. Rather we have the array organized like this
a[0][0]
\
1 2 3 4 5 6
\___/ \___/
"a[0]" / \____ "a[1]"
or something like this. The picture likely does not explain it well, but currently I can't do better.
void main()
{
clrscr();
int in[10][10];
int out[10][10];
int row,column,i,j;
printf("enter row");
scanf("%d",&row);
printf("Enter column");
scanf("%d",&column);
//storing values in matrix
for(i=1;i<=row;i++)
{
for(j=1;j<=column;j++)
{
printf("Enter (%d,%d)th value",i,j);
scanf("%d",&in[i-1][j-1]);
}
}
//show stored values
printf("\ninput is\n\n");
for(i=0;i<row;i++)
{
for(j=0;j<column;j++)
{
printf("%d\t",in[i][j]);
}
printf("\n");
}
//show transposed value. it is also stored in out matrix
printf("\nOutput is\n\n");
for(i=0;i<column;i++)
{
for(j=0;j<row;j++)
{
printf("%d\t",in[j][i]);
out[i][j]=in[j][i];
}
printf("\n");
}
getch();
}
//////////////////////////////////////
input matrix is stored in in[][] matrix and output matrix stored in out[][] matrix.
this program will work for any matrix with row and column below 10 if we increase the matrix variable value ,it will work for larger matrix also .
Here is a rather naive implementation. I'm pretty sure there are more efficient ways, but this is all I could think of.
void transpose(int **src, int **dest, int rows, int cols){
int i,j;
for(i=0; i<rows; i++){
for(j=0; j<cols; j++){
dest[j][i] = src[i][j];
}
}
}
int main(void){
int oldar[2][3] = {{1,2,3},{4,5,6}};
int newar[3][2];
transpose(oldar, newar, 2, 3);
}
Double pointers can represent double arrays, so there is no need to allocate on the heap here.
This is a half-done program the way I would do it in C:
int main()
{
int **data;
int rows = 0,
columns = 0;
char in[256];
int *irow;
// Get user input.
for(rows = 0; 1; ++rows)
{
scanf("%255s", in);
if(strcmp(in, "exit") == 0)
break;
// Parse row here. Remove all the tabs. Set column count.
for(int icolumn = 0; 1; ++icolumn)
{
/* ... */
}
// Set columns if first time.
if(rows == 0)
columns = icolumn;
// Check to make sure user inputs correct amount of columns.
if(columns != icolumns)
{
printf("OMG! The user is a hacker!\n");
break;
}
// Push parsed row into **data.
data[rows] = irow;
}
// Display output.
for(int i = 0; i < columns; ++i)
{
for(int j = 0; j < rows; ++j)
{
printf("%d\t", data[j][i]);
}
printf("\n");
}
return 0;
}
I'm a C++ programmer, so the user input part is kind of messed up.
hey here is a simple solution without using malloc,i did this when i was on the 0th level for c and had no idea about "alloc.h" functions,
You can have the square array having #rows = #cols = max(#rows,#cols),if we take your example then the matrix would be a 3x3 matrix,then add any special char in the blank entries,so the matrix will look like this
matrix:1 2 3
4 5 6
# # #
now you can easily convert the matrix in the way you want...
Bottom line:To make the matrix operations simpler try to convert them in square matrix...
One more thing using MALLOC is the best possible way ,this is just in case you are not handy with all those alloc.h function defs...
theoretically, you have two arrays
Array x and y
Int grades [x] [y]
you can swap these two arrays and you get
int grades [y] [x]
to do that there are many methods e.g. by copying the arrays to another two 1D, or one 2D Array, or simple Pointer Swap