Dynamic 2D array and memory free - c

I'm having a big troubles figuring out how to rightfully create a 2D dynamic array, how to assert the memory and how to free it in the end.
I'll show you parts of my code, and please tell me what I'm doing wrong.
I declare on the dynamic array in main function and send it to BuildMatrix function that is supposed to assert the needed memory to the array and fill it.
that's how I declared on the array and send it to the function Build:
int row, column, i, j;
int **matrix;
BuildMatrix(&matrix, row, column);
now thats BuildMatrix decleration:
void BuildMatrix(int*** matrix, int row, int column);
And that's how I assert the memory (row and column have values that the user chose)
matrix =malloc(row * sizeof(int *));
for (i = 0; i < row; i++)
matrix[i] =malloc(column * sizeof(int));
Now so far everything works just fine, but when I try to free the memory, I get break point error
That's the function I used for freeing the memory:
void ExitAndFree(int** matrix, int row) {
int i;
for (i = 0; i < row; i++) {
free(matrix[i]);
}
free(matrix);
}
The debugger show me that the error is on the first free (if I remove the first one, the second gives the error)
There is also another problem, but I think its to much for now, I'll ask later... :P
Thanks for your help!!
P.S: If you got any good tutorials about pointers and dynamic arrays (I'd rather 2D+ arrays) I'd appreciate it a lot.

I do not think you need a *** pointer here, instead BuildMatrix could just return ** to main(). This design change would make your program easier, as working with *** can be a pain sometimes.
You also are not checking the return values of malloc() and scanf(), which can lead to future problems, and it's just safer to check those first. I also suggest you Don't cast result of malloc(), as this is not really needed in C.
With your errors of free() from the code you posted on #flintlock's answer, There is an inconsistency in your code:
You have declared:
void ExitAndFree(int** matrix, int row)
When this should be instead:
void ExitAndFree(int*** matrix, int row)
This change is needed in your code because you are calling &matrix in main for ExitAndFree(), so having **matrix in this function is not good enough. Again, this is because the code is using ***, which makes life harder.
Your code seems to work here with this change.
With these recommendations, you can also implement your program like this:
#include <stdio.h>
#include <stdlib.h>
int **BuildMatrix(int row, int column);
void PrintAndFree(int **matrix, int row, int column);
int main(void) {
int **matrix, row, column;
printf("\nPlease enter number of rows:\n");
if (scanf("%d", &row) != 1) {
printf("Invalid rows.\n");
exit(EXIT_FAILURE);
}
printf("\nPlease enter number of columns:\n");
if (scanf("%d", &column) != 1) {
printf("Invalid columns.\n");
exit(EXIT_FAILURE);
}
matrix = BuildMatrix(row, column);
PrintAndFree(matrix, row, column);
return 0;
}
int **BuildMatrix(int row, int column) {
int **matrix, rows, cols;
matrix = malloc(row * sizeof(*matrix));
if (matrix == NULL) {
printf("Cannot allocate %d rows for matrix.\n", row);
exit(EXIT_FAILURE);
}
for (rows = 0; rows < row; rows++) {
matrix[rows] = malloc(column * sizeof(*(matrix[rows])));
if (matrix[rows] == NULL) {
printf("Cannot allocate %d columns for row.\n", column);
exit(EXIT_FAILURE);
}
}
printf("\nPlease enter values to the matrix:\n");
for (rows = 0; rows < row; rows++) {
for (cols = 0; cols < column; cols++) {
if (scanf("%d", &matrix[rows][cols]) != 1) {
printf("Invalid value entered.\n");
exit(EXIT_FAILURE);
}
}
}
return matrix;
}
void PrintAndFree(int **matrix, int row, int column) {
int rows, cols;
printf("\nYour matrix:\n");
for (rows = 0; rows < row; rows++) {
for (cols = 0; cols < column; cols++) {
printf("%d ", matrix[rows][cols]);
}
free(matrix[rows]);
matrix[rows] = NULL;
printf("\n");
}
free(matrix);
matrix = NULL;
}

Here a copy&paste ready example...
#include <stdlib.h>
void BuildMatrix(int*** matrix, int row, int column) {
*matrix = malloc(row * sizeof(int *));
int i;
for (i = 0; i < row; i++)
(*matrix)[i] = malloc(column * sizeof(int));
}
void ExitAndFree(int** matrix, int row) {
int i;
for (i = 0; i < row; i++) {
free(matrix[i]);
}
free(matrix);
}
int main()
{
int row = 10, column = 10;
int **matrix;
BuildMatrix(&matrix, row, column);
ExitAndFree(matrix, row);
return 0;
}
However I would strongly recommend against working with raw pointers and separate variables for matrix directly. A better solution Software Engineering wise would be to either use an existing matrix library, or writer your own matrix library in C with struct...

Related

Got stuck in a customizable dimensional matrix operation program

`
//MATRIX INPUT
#include<stdio.h>
int main(void)
{
//declaring variables
size_t row=0;
size_t column=0;
int limit=0;
int en=0;
int mat[row][column];
//starting
printf("ENTRE THE NUMBER OF R
EPETITIONS OF MATRIX
INPUT:");
scanf("%d",&limit);
//starting loop
for(int i=0;i<=(limit-1);++i)
{
printf("\nINITIALIZED THE
MATRIX-%d...\n",i+1);
printf("\nENTER ROW
NUMBER FOR MATRIX:\n");
scanf("%d",&row);
printf("\nENTER COLUMN
NUMBER FOR MATRIX:\n");
scanf("%d",&column);
//entering the entries..
for(int j=0; j<row ;++j)
{
for(int k=0;
k<column;++k)
{
printf("ENTRY (%d,%d):",(j+1),(k+1));
scanf("%d",&mat[k][j]);
}
}
}
//starting the console output
of matrix
int v=0;
printf("Which matrix do you
want to see?\n");
scanf("%d",&v);
for(v=0; v<=limit; ++v)
{
for(int l=0; l<row; ++l)
{
for( int m=0; m<column;
++m)
{
printf("%2d", mat[m][l]);
}
}
}
return 0;
}`
I have written a program in C where the user can firstly define the number of matrices. Then, the dimension of individual matrix is defined. I have successfully proceeded to individual matrix input. But I am stuck in writing the operational codes like multiplying and adding matrices as well as to write code for showing output in matrix style.
How to fix this?
incomplete source code
Console of output
I couldn't get the part why you created an empty static array, and then changed its boundaries at least tried to change. However, I believe dynamic array allocation would serve your purpose better than static one. I implemented a 3D array that has the first index as matrices, the second index as rows of the current matrix, and the third index as columns of the current matrix. Also, fixed the display method, you have been using. However, there can be different-sized matrices for each matrix you have. Therefore, I implemented another list to keep track of the rows and columns. Lastly, I put two links at the top of the code that you can implement addition and multiplication operations by yourself. You can see the code from here:
//MATRIX INPUT
#include<stdio.h>
#include<stdlib.h>
//Add two matrices
//https://www.programmingsimplified.com/c-program-add-matrices
//Multiplying two matrices
//https://www.programiz.com/c-programming/examples/matrix-multiplication
void display_matrix(int** , int , int );
void fillWithNum(int**,int,int,int);
int main(void)
{
//declaring variables
size_t row=0;
size_t column=0;
int limit=0;
int en=0;
int ***mat;
//starting
printf("ENTRE THE NUMBER OF REPETITIONS OF MATRIX INPUT:");
scanf("%d",&limit);
mat = (int***)malloc(sizeof(int**) * limit);
//Two keep track of the rows and columns
//First index of the second dimension will be rows, and
//second index will be columns of matrices at the mat variable.
int **indexingList;
indexingList = (int**)malloc(sizeof(int*) * limit);
for(int i=0;i<limit;++i) {
indexingList = (int*) malloc(sizeof(int) * 2);
}
//starting loop
for(int i=0;i<limit;i++)
{
printf("\nINITIALIZED THE MATRIX-%d...\n",i+1);
printf("\nENTER ROW NUMBER FOR MATRIX:\n");
scanf("%d",&row);
printf("\nENTER COLUMN NUMBER FOR MATRIX:\n");
scanf("%d",&column);
mat[i] = (int**) malloc(row * sizeof(int*));
for (int j = 0;j < row;j++) {
mat[i][j] = (int*)malloc(column * sizeof(int));
}
//entering the entries..
for(int j=0;j < row;j++)
{
for(int k=0;k < column;k++)
{
printf("ENTRY (%d,%d):",(j+1),(k+1));
scanf("%d",&mat[i][j][k]);
}
}
indexingList[i][0] = row;
indexingList[i][1] = column;
}
//starting the console output of matrix
int v=1;
printf("Which matrix do you want to see?\n");
scanf("%d",&v);
//v-1 because if user want to display first matrix it should be 0, so user will enter 1
//therefore, 1-1 will give us 0 to display 0 index matrix
display_matrix(mat[v-1], indexingList[v-1][0], indexingList[v-1][1]);
//Problem at freeing memory for some purpose crash at here.
//I couldn't figure it out as well.
for(int i = 0;i < limit;i++) {
for(int j = 0;j < indexingList[i][0];j++) {
free(mat[i][j]);
}
free(mat[i]);
}
free(mat);
for(int i = 0;i < limit;i++) {
free(indexingList[i]);
}
free(indexingList);
return 0;
}
void display_matrix(int** matrix, int r, int c) {
for(int i = 0 ;i < r;i++){
for(int j = 0;j < c;j++) {
printf("%d\t",matrix[i][j]);
}
printf("\n");
}
}
//Test purpose
void fillWithNum(int** arr,int r, int c, int num) {
for (int i = 0;i<r;i++) {
for(int j = 0;j<c;j++) {
arr[i][j] = num;
}
}
}
However, this code also crashes at the end of the memory-freeing part. I couldn't figure out why, but if someone finds it out as well, I would appreciate it.

Function changes variables not involved in the function (in c)

So I'm trying to make a program to row reduce a matrix (there are probably a thousand way better ways to do it but I'm trying to figure it out on my own). I have a function that is supposed to make two rows of different arrays equal. It doesn't even take the row variable as an input or have anything to do with it but for some reason after the function is called the row variable switches from whatever was put into the keyboard to 1072693248. I also just noticed a problem with the col variable where it is set to 0 the second time the for loop it is in happens. I have no clue what is causing these problems so any help would be really appreciated. I'm just going to post the entire code since I'm not sure which part is causing the problem (its probably super messy, my only coding experience is one super basic beginner course in c in university). (I put in some printfs to print row or col in different spots to try and find out where the problem was happening).
#include <stdlib.h>
void printArray(double a[][100], int rows, int columns);
void addRow(double a[][100], int columns, int rowToAdd, int rowAddedTo);
void addRowBetweenArrays(double arrayAddedTo[][100],double arrayAdded[][100], int columns, int rowToAdd, int rowAddedTo);
void multiplyRow(double a[][100], int columns, int rowMultiplied, double mupltiplyBy);
void switchRows(double a[][100], int columns, int rowOne, int rowTwo);
//void makeRowsEqual(double rowMadeEqual[][100], double madeEqualTo[][100], int rowInMadeEqualTo, int RowInMadeEqual, int columns);
void makeTwoArraysRowsEqual(double arrayMadeEqual[][100], double arrayMadeEqualTo[][100], int rowMadeEqual, int rowMadeEqualTo, int column);
int main()
{
int row, col, i, j, checkReduced, rowIsReduced = 0, focus;
double multiplyFactor;
printf("Enter the size of your array (rows columns): ");
scanf("%d %d", &row, &col);
double array[row][100];
double tempRow[1][100];
for(j = 0; j < row; j++)
{
printf("Enter row %d: ", j + 1);
for(i = 0; i < col; i++)
{
scanf("%lf", &array[j][i]);
}
printf("\n");
}
printf("\n\nUnreduced array:\n");
printArray(array, row, col);
//start the reducing
for(focus = 0; focus < row; focus++)
{
rowIsReduced = 0;
for(i = 0; i < col; i++)
{
if(i == focus)
{
i++;
}
if(array[i][focus] != 0)
{
rowIsReduced = 1;
}
}
if(rowIsReduced == 1)
{
//now start the reducing process
for(i = 0; i < row; i++)
{
printf("\n%d\n", row);
if(i == focus)
{
i++;
}
//skip the row we are focusing on
//first check if we even need to manipulate the row
if(array[i][focus] != 0)
{
if(array[focus][focus] * array[i][focus] > 0)
{
printf("\n%d\n", row);
//then check if we need to add or subtract
//make temp row equal to focus row
printf("Column before function: %d", col);
makeTwoArraysRowsEqual(tempRow, array, 1, focus, col);
// to check order: makeTwoArraysRowsEqual(double arrayMadeEqual[][100], double arrayMadeEqualTo[][100], int rowMadeEqual, int rowMadeEqualTo, int column)
printf("\nAfter make rows equal: %d\n", row);
//now multiply both rows
multiplyFactor = array[i][focus];
multiplyRow(tempRow, col, 1, multiplyFactor);//getting stuck here
//multiplyRow(double a[][100], int columns, int rowMultiplied, double mupltiplyBy);
multiplyFactor = -1 * array[focus][focus];
multiplyRow(array, col, i, multiplyFactor);
//then add them
addRowBetweenArrays(array, tempRow, col, 1, i);
printf("Made it to end of the loop");
}
else //could also use: if(array[focus][focus] * array[i][focus] < 0)
{
//then check if we need to add or subtract
//make temp row equal to focus row
//makeRowsEqual(tempRow, array, focus, 1, col); need to switch this to new format
//now multiply both rows
multiplyRow(tempRow, col, 1, array[i][focus]);
multiplyRow(array, col, i, array[focus][focus]);
//then add them
addRowBetweenArrays(array, tempRow, col, 1, i);
}
//now the rows are added so there is a zero in the focus column
//will need to check if any rows are zero and move them to the bottom, have to figure that out
//will also need to divide all the rows by their first non zero term
}
printf("\n%d\n", row);//rows are acting weird, getting to be a really big number after the first run
}
printf("Made it out of i loop");
}
}
printf("\n\Reduced array:\n");
printArray(array, row, col);
return 0;
}
void printArray(double a[][100], int rows, int columns)
{
int i, j;
for(j = 0; j < rows; j++)
{
for(i = 0; i < columns; i++)
{
printf("%6.2lf ", a[j][i]);
}
printf("\n");
}
}
void addRow(double a[][100], int columns, int rowToAdd, int rowAddedTo)
{
int i;
for(i = 0; i < columns; i++)
{
a[rowAddedTo][i] += a[rowToAdd][i];
}
return 0;
}
void addRowBetweenArrays(double arrayAddedTo[][100],double arrayAdded[][100], int columns, int rowToAdd, int rowAddedTo)
{
int i;
for(i = 0; i < columns; i++)
{
arrayAddedTo[rowAddedTo][i] += arrayAdded[rowToAdd][i];
}
}
void multiplyRow(double a[][100], int columns, int rowMultiplied, double mupltiplyBy)
{
int i;
for(i = 0; i < columns; i++)
{
a[rowMultiplied][i] *= mupltiplyBy;
}
}
void switchRows(double a[][100], int columns, int rowOne, int rowTwo)
{
int i, temp;
for(i = 0; i < columns; i++)
{
temp = a[rowOne][i];
a[rowOne][i] = a[rowTwo][i];
a[rowTwo][i] = temp;
}
}
/*
void makeRowsEqual(double rowMadeEqual[][100], double madeEqualTo[][100], int rowInMadeEqualTo, int rowInMadeEqual, int columns)
{
int i;
printf("In function: made = to: %d, made =: %d", rowInMadeEqualTo, rowInMadeEqual);
for(i = 0; i < columns; i++) {
rowMadeEqual[rowInMadeEqual][i] = madeEqualTo[rowInMadeEqualTo][i];
}
printf("\nMade equal:\n");
printArray(rowMadeEqual, 1, columns);
printf("\nMade equal to:\n");
printArray(madeEqualTo, 2, columns);
}*/
void makeTwoArraysRowsEqual(double arrayMadeEqual[][100], double arrayMadeEqualTo[][100], int rowMadeEqual, int rowMadeEqualTo, int column)
{
int i;
for(i = 0; i < column; i++) {
arrayMadeEqual[rowMadeEqual][i] = arrayMadeEqualTo[rowMadeEqualTo][i];
}
printf("Column in function: %d", column);
}
Here is a sample output:
Enter the size of your array (rows columns): 2 2
Enter row 1: 1
2
Enter row 2: 2
4
Unreduced array:
1.00 2.00
2.00 4.00
2
2
Column before function: 2Column in function: 2
After make rows equal: 1072693248
Made it to end of the loop
1072693248
1072693248
1072693248
Column before function: 0Column in function: 0
After make rows equal: 1072693248
Made it to end of the loop
1072693248
1072693248
1072693248
Column before function: 0Column in function: 0
After make rows equal: 1072693248
Made it to end of the loop
1072693248
1072693248
Process returned -1073741819 (0xC0000005) execution time : 3.808 s
Press any key to continue.
P.S. Sorry if this question is formatted poorly or something, this is my first question and I've hardly used stack overflow as of right now.
The problem is this line:
makeTwoArraysRowsEqual(tempRow, array, 1, focus, col);
The third argument is used as the row index in tempRow to copy to. tempRow is declared:
double tempRow[1][100];
Since it only has 1 row, the highest row index is 0, but you're copying to row 1, which is outside the array, resulting in undefined behavior.
You should use row index 0:
makeTwoArraysRowsEqual(tempRow, array, 0, focus, col);
You have similar problems in the calls to other functions that use tempRow. They all pass 1 when it should be 0.
It's not clear why tempRow even needs to be 2-dimensional, since it only has one row. Just make it a 1-dimensional array, and remove the row index from all the functions that use it.

Call a function that receives an array using a pointer

So I've this:
int main()
{
int workers;
printf("How many workers are there?\n");
scanf("%d", &workers);
printf("What are their preferences?\n");
int *pref = malloc(workers * sizeof(int));
if (pref == NULL)
return -1;
fillPreferences(pref, workers);
return 0;
}
I want now to fill the "pref" 2d array in this function:
void fillPreferences(int pref[][], int size)
{
for (int i=0;i<size;i++)
{
for (int j=0;j<size;j++)
{
scanf(" %d", &pref[i][j]);
}
}
}
It doesn't work, probably because I'm using the pointer wrong. How can I use malloc and then call a function and receive the values in the 2d array by doing pref[i][j]? (Note that I'm not looking to do something like scanf(..., &pref+i) or whatever. I need to actually use that 2d array.
Thanks :)
When you write a[i], it is turned into *(a+i). That is, a[i] accesses the memory by a+i address (well, it is a+i*sizeof(element) even).
As such, a[i][j] means *(*(a+i)+j). Two memory accesses. For this to work, your a should be an array of arrays. That is, you need to malloc its elements first and then malloc a memory to hold them.
In your particular case, i doubt you need it. What you need is make it 1D-array (which is it already) and calculate index from your two indices in whatever fashion you wish.
Your pref array is 1D so you can make it in this way:
#include <stdio.h>
#include <stdlib.h>
void fillPreferences(int **pref, int size)
{
int prefNum=0;
for (int i=0;i<size;i++)
{
puts("Number of preferences");
scanf("%d",&prefNum);
pref[i]=malloc(sizeof(int)*prefNum);
puts("Enter preferences");
for(int j=0;j<prefNum;j++){
scanf(" %d", &pref[i][j]);
}
}
}
int main()
{
int workers;
printf("How many workers are there?\n");
scanf("%d", &workers);
printf("What are their preferences?\n");
int **pref = malloc(workers * sizeof(int *));
if (pref == NULL)
return -1;
fillPreferences(pref, workers);
// Show values
printf("%d %d %d",pref[0][0],pref[1][0],pref[2][0]);
return 0;
}
You allocate memory for a 1D array, but the function you have is designed to accept a 2D array and fill it (although the function definition is incorrect and won't compile).
Corrected code:
#include <stdio.h>
#include <stdlib.h>
void fillPreferences(int** pref, int size)
{
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
scanf("%d", &pref[i][j]);
}
}
}
int main()
{
int workers;
printf("How many workers are there?\n");
scanf("%d", &workers);
printf("What are their preferences?\n");
int **pref = malloc(workers * sizeof(int*));
if (pref == NULL)
return -1;
for(int i = 0; i < workers; i++)
{
pref[i] = malloc(workers * sizeof(int));
if(pref[i] == NULL)
{
for(int j = 0; j < i; j++)
free(pref[j]);
free(pref);
return -1;
}
fillPreferences(pref, workers);
/* Don't forget to `free` everything after its use! */
return 0;
}

C - allocating a matrix in a function

I am trying to allocate a matrix using a function that takes its dimensions and a triple pointer. I have allocated an int** (set to NULL) and I am passing its address as the function's argument. That gives me a mem access violation for some reason.
void allocateMatrix(int ***matrix, int row, int col)
{
int i;
if((*matrix = (int**)malloc(row * sizeof(int*))) == NULL)
{
perror("There has been an error");
exit(EXIT_FAILURE);
}
for(i = 0; i < row; ++i)
{
if((*matrix[i] = (int*)malloc(col * sizeof(int))) == NULL)
{
perror("There has been an error");
exit(EXIT_FAILURE);
}
}
}
/* main.c */
int** matrix = NULL;
allocateMatrix(&matrix, MATRIX_ROW, MATRIX_COL); //error
You need to change
if((*matrix[i] = (int*)malloc(col * sizeof(int))) == NULL)
to
if(((*matrix)[i] = (int*)malloc(col * sizeof(int))) == NULL)
// ^ ^
You need to dereference matrix before using the array subscript.
*matrix[i] is equivalent to *(matrix[i])
It's a problem of operator precedence. In
if ((*matrix[i] = (int*)malloc( ... ))
the default precedence is *(matrix[i]), while you should use (*matrix)[i].
I would still recommend to allocate the matrix as a contiguous array instead as a array of pointers to arrays.
I have made a solution program for gcc C11/C99 with apropriate allocation funtions based on links:
http://c-faq.com/aryptr/dynmuldimary.html
http://c-faq.com/aryptr/ary2dfunc3.html
After some discussion in comments, it is clear that matrix2 is correctly allocated, it can be passed to this function fn(int row, int col, int array[col][row]) as matrix2[0] (data in one dimensional array) with a cast to (double (*)[])
//compile with gcc --std=c11 program.c
#include <stdio.h>
#include <stdlib.h>
#define MX 9
#define MY 14
void input_matrix(int row, int column, double matrix[row][column]);
void print_matrix(int row, int column, double matrix[row][column]);
double **alloc_matrix2(int row, int column);
double *alloc_matrix3(int row, int column);
void *alloc_matrix4(int row, int column);
int main()
{
int i=MX, j=MY;
printf("Generate input values and print matrices with functions fn(int w, int k, double matrix[w][k]) (in C99 and C11)\n");
double matrix1[i][j];
input_matrix(MX,MY,matrix1);
printf("matrix static\n");
print_matrix(MX,MY,matrix1);
double **matrix2; //data of matrix2 is just matrix3
matrix2=alloc_matrix2(MX,MY);
input_matrix(MX,MY,(double (*)[])(*matrix2));
printf("matrix two times allocated one for pointers, the second for data (double (*)[])(m[0])\n");
print_matrix(MX,MY,(double (*)[])(matrix2[0]));
free(*matrix2);
free(matrix2);
double *matrix3=alloc_matrix3(MX,MY);
input_matrix(MX,MY,(double (*)[])matrix3);
printf("matrix allocated as two-dimensional array\n");
print_matrix(MX,MY,(double (*)[])matrix3);
free(matrix3);
j=MY;
double (*matrix4)[j];
matrix4 = (double (*)[])alloc_matrix4(MX,MY);
input_matrix(MX,MY,matrix4);
printf("matrix allocated via pointer to array m = (double (*)[])malloc(MX * sizeof(*m))\n");
print_matrix(MX,MY,matrix4);
free(matrix4);
printf("\nThe End!\n");
return 0;
}
void input_matrix(int row, int column, double matrix[row][column]){
for(int i=0; i<row; i++){
for(int j=0; j<column; j++)
matrix[i][j]=i+1;
}
}
void print_matrix(int row, int column, double matrix[row][column]){
for(int i=0; i<row; i++){
for(int j=0; j<column; j++)
printf("%.2lf ", matrix[i][j]);
printf("\n");
}
}
double **alloc_matrix2(int row, int column){
double **matrix;
matrix=malloc(row*sizeof(double*));
matrix[0] = (double *)malloc(row*column*sizeof(double));
for(int i = 1; i < row; i++)
matrix[i] = matrix[0]+i*column;
return matrix;
}
double *alloc_matrix3(int row, int column){
double *matrix;
matrix=malloc(row*column*sizeof(double));
return matrix;
}
void *alloc_matrix4(int row, int column){
double (*matrix)[column];
matrix = (double (*)[])malloc(row*sizeof(*matrix));
return matrix;
}

Dynamically Allocating a Matrix from Input - C

I've been trying this code and it's not working out very well.
void *matrix_allocate_variable (int size)
{
void *p1;
if ((p1=(int*)malloc(size))==NULL){
printf("out of memory.\n");
exit(1);
}
return p1;
}
Here I created a function that call's malloc and exits upon error, so that I could use it in my next function:
void matrix_new(int **matrices, int *row_counts, int *column_counts, char specifier)
{
int index, i;
index= (int)(specifier-'A');
scanf("%d",&row_counts[index]);
scanf("%d",&column_counts[index]);
matrices[index]= (int*)matrix__allocate_variable(sizeof(int)* (row_counts[index]*column_counts[index]);
Here is where I am having problems. I'm trying to have the user enter some input for creating the matrix, but I'm having lots of problems trying to get this working. Can some one help me start this off?
PS. For more details, I'm creating functions in functions.c, this are what I have so far. I have a main.c which calls these functions so that later on I can add, subract, and transpose, but as of now I am trying to enter in data which is what I'm having lot of trouble with. Here is my main.c where I call the functions.
/* Pointer to the set of matrix registers. */
int **matrices = NULL;
/* row_counts[i] stores the number of rows in matrix i */
int *row_counts = NULL;
/* column_counts[i] stores the number of columns in matrix i */
int *column_counts = NULL;
/**********************************************************************
Skeleton code part B: suggested form for selected variable initializations
**********************************************************************/
/* Initialize the matrix set. */
matrices = (int**) matrix_allocate_variable(...);
column_counts = (int *)matrix_allocate_variable(...);
row_counts = (int *)matrix_allocate_variable(...);
char call[2];
int error = 2;
do {
printf ( "> ");
if (scanf ("%1s", call) !=1) {
fprintf (stderr, "Command not found. \n");
exit (1);
}
switch (call [0]) {
case 'A': matrix_new(matrices,row_counts,column_counts,'A');
break;
case 'B': matrix_new(matrices,row_counts,column_counts,'B');
break;
case 'C': matrix_new(matrices,row_counts,column_counts,'C');
break;
case 'D': matrix_new(matrices,row_counts,column_counts,'D');
break;
case '+': matrix_add(matrices,row_counts,column_counts);
break;
case '^': matrix_tranpose(matrices,row_counts,column_counts);
break;
case '*': matrix_multiply(matrices,row_counts,column_counts);
break;
case '$': exit (1);
default : fprintf (stderr, "Command not found. \n");
}
} while (error != 1);
return 0;
}
Any help will be good and any pointers in what I should do next is great also. Thank you so so much every one.
Hi this is a sample code to create one matrix using malloc.
(This should give you some insight on how to create an array of matrices. If it doesn't then let me know.)
#include <stdio.h>
#include <stdlib.h>
// Creates a matrix given the size of the matrix (rows * cols)
int **CreateMatrix(int rows, int cols) {
int **matrix = malloc(sizeof(int*) * rows);
int row;
for (row = 0; row < rows; row++) {
matrix[row] = malloc(sizeof(int) * cols);
}
return matrix;
}
// Take input for the matrix.
void MatrixInput(int **matrix, int rows, int cols) {
int row, col;
for (row = 0; row < rows; row++) {
for (col = 0; col < cols; col++) {
scanf("%d", &matrix[row][col]);
}
}
}
void PrintMatrix(int **matrix, int rows, int cols) {
int row, col;
for (row = 0; row< rows; row++) {
for (col = 0; col < cols; col++) {
printf("%d ", matrix[row][col]);
}
printf("\n");
}
}
int main() {
int **matrix;
int rows = 5;
int cols = 4;
matrix = CreateMatrix(rows, cols);
MatrixInput(matrix, rows, cols);
PrintMatrix(matrix, rows, cols);
}
Here is an example of creating and freeing memory for a two dimendional array...
(easily modifiable for other types)
int ** Create2D(int **arr, int cols, int rows)
{
int space = cols*rows;
int y;
arr = calloc(space, sizeof(int));
for(y=0;y<cols;y++)
{
arr[y] = calloc(rows, sizeof(int));
}
return arr;
}
void free2DInt(int **arr, int cols)
{
int i;
for(i=0;i<cols; i++)
if(arr[i]) free(arr[i]);
free(arr);
}
Use it like this:
#include <ansi_c.h>
int main(void)
{
int **array=0, i, j;
array = Create2D(array, 5, 4);//get the actual row/column values from reading the file once.
for(i=0;i<5;i++)
for(j=0;j<4;j++)
array[i][j]=i*j; //example values for illustration
free2DInt(array, 5);
return 0;
}

Resources