Matrix addition in c using malloc not allowing full input - c

So my assignment is to add matrices (they don't have to be square but the two matrices will always be the same size) by dynamically allocating the space for a 2-D array, and I used a double pointer. My function to get the user-inputted matrices is as follows:
void matrixEntry(const int rowNum, const int colNum, const char
matrixNum, int** matrix) {
int i, j, k;
matrix = (int**) malloc(rowNum * sizeof(int*));
for (k = 0; k < rowNum; ++k) {
matrix[i] = (int*)malloc(colNum * sizeof(int));
}
printf("Enter Matrix %c\n", matrixNum);
for (i = 0; i < rowNum; ++i) {
for (j = 0; j < colNum; ++j) {
scanf("%d", &matrix[i][j]);
}
}
}
where I call it in main twice as such:
matrixEntry(rowNum, colNum, matA, matrixOne);
matrixEntry(rowNum, colNum, matB, matrixTwo);
However, when I run the program I'm only allowed to enter the first row of Matrix A before the program stops running. I think this is because I didn't allocate enough space for the 2nd row, but I'm not sure where my mistake is. My thought process when allocating the space was that
matrix = (int**) malloc(rowNum * sizeof(int*));
allocated the space for the rowNum number of rows, and then the for loop allocated the space for the number of columns. Is this correct?

Related

segmentation fault in functions about matrices in c

I implemented several functions about matrices related to arrays and pointers and everytime i run the code i get a segmentation fault.
It would be nice if someone could revise my code and maybe explain why this error occurs.
Function 1 should create a dynamically allocated matrix with the correspondent cols and rows. It should also initialize the elements to 0 (i have to use xmalloc and cannot use xcalloc) and return a pointer to the created matrix.
Function 2 gets an 1D-Array of rows * cols and should create a dynamically allocated matrix of these numbers.
Function 3 should print out a matrix.
Function 4 should free a created matrix.
This is my code
struct Matrix {
int rows; // number of rows
int cols; // number of columns
double** data; // a pointer to an array of n_rows pointers to rows; a row is an array of n_cols doubles
};
typedef struct Matrix Matrix;
/**
Creates a zero-initialized matrix of rows and columns matrix.
#param[in] n_rows number of rows
#param[in] n_cols number of columns
#return a pointer to an array of n_rows pointers to rows; a row is an array of n_cols doubles
*/
Matrix* make_matrix(int n_rows, int n_cols) {
double **m = xmalloc(n_rows * sizeof(double));
for(int row = 0; row < n_cols; row++){
m[row] = xmalloc(n_cols * sizeof(double));
}
Matrix matrixx = {n_cols, n_rows, m};
Matrix *pointer;
pointer = &matrixx;
return pointer;
}
/**
Creates a zero-initialized matrix of rows and columns matrix.
#param[in] data an array of doubles, ordered row-wise
#param[in] n_rows number of rows
#param[in] n_cols number of columns
#return a pointer to an array of n_rows pointers to rows; a row is an array of n_cols doubles
*/
Matrix* copy_matrix(double* data, int n_rows, int n_cols) {
Matrix *pointer = make_matrix(n_rows,n_cols);
int k = 0;
double **Matrix = (double **)xmalloc(sizeof(double *) * n_rows);
for(int i = 0; i < n_rows; i++){
Matrix[i] = (double *)xmalloc(sizeof(double ) * n_cols);
}
do{
for(int i = 0; i < n_rows; i++){
for(int j = 0; j < n_cols; j++){
Matrix[i][j] = data[k];
k++;
}
}
}while (k < sizeof(data));
return pointer;
}
/**
#param[in] m the matrix to print
*/
void print_matrix(Matrix* m) {
for(int row = 0; row < m->rows; row++){
for(int column = 0; column < m->cols; column++){
printf("%.f ", m->data[row][column]);
}
println();
}
println();
}
//#param[in] m the matrix to free
void free_matrix(Matrix* m) {
for (int i = 0; i < m->cols; i++)
free(m->data[i]);
free(m->data);
free(m);
}
I tried to allocate the memory with xmalloc in function 1,2 and 4 but somehow this does not work out and i get a segmentation fault error
In the first line of the make_matrix function, you might want to use only one asterisk because two asterisks mean your pointing to another pointer and I don't see where another pointer would be there
try changing it from this:
double **m = xmalloc(n_rows * sizeof(double));
to this:
double *m = xmalloc(n_rows * sizeof(double));
if that doesn't work then than tell me I'll look at the code again and try to spot another error

Can someone explain me what is going on in this statement?

Basically i understand pointers. But when it comes to dynamic allocation for matrices which also involve pointers, i'm getting lost in the process. I wanna know how can i translate this segment of code in order to understand it.
(*a)[i] = (int*)malloc((*m) * sizeof(int));
The function for reading the matrix looks like this:
void reading(int *n, int *m, int ***a) {
int i, j;
printf("n=");
scanf("%d", &*n);
printf("m=");
scanf("%d", &*m);
(*a) = (int**)malloc((*n) * sizeof(int*));
for (i = 0; i < *n; i++)
(*a)[i] = (int*)malloc((*m) * sizeof(int));
for (i = 0; i < *n; i++) {
for (j = 0; j < *m; j++) {
printf("a[%d][%d]=", i, j);
scanf("%d", &(*a)[i][j]);
}
}
}
And also what is the meaning of ***a in the declaration. I was told at college that te first asterisk stands for dynamic allocation and the other two's from the fact that is a matrix involved. For vectors dynamic allocation is **v and so on... but i can't naturally explain it in my mind in order understand what is happening in it.
First let me answer your question about this specific line:
(*a)[i] = (int*)malloc((*m) * sizeof(int));
What this is doing is allocating an array of exactly *m integers and saving a pointer to it into the array *a of pointers to int, which was previously allocated as:
(*a) = (int**)malloc((*n) * sizeof(int*));
Now, if it still isn't clear what is going on, re-writing the code in a more meaningful way will help. To make things easier, you can use temporary variables to work, and assign the values to the pointers passed as arguments only at the end of the function. Using more meaningful names also helps a lot.
void read_matrix(int *rows, int *columns, int ***matrix) {
int i, j, r, c;
int **mat;
printf("n = ");
scanf("%d", &r);
printf("m = ");
scanf("%d", &c);
// Allocate space for a matrix (i.e. an array of r integer pointers).
mat = malloc(r * sizeof(int*));
// Allocate space for each row of the matrix (i.e. r arrays of c integers).
for (i = 0; i < r; i++)
mat[i] = malloc(c * sizeof(int));
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) {
printf("a[%d][%d] = ", i, j);
scanf("%d", &mat[i][j]);
}
}
*rows = r;
*columns = c;
*matrix = mat;
}
Since we now moved the assignment of the values to the arguments at the end of the function, we got rid of all the annoying pointer dereference operators (*), and the code looks way cleaner.
You can see that what previously was:
(*a)[i] = (int*)malloc((*m) * sizeof(int));
now became:
mat[i] = malloc(c * sizeof(int));
Which is much easier to understand. This is allocating space for an array (a row of the matrix) holding c integers.
What previously was:
(*a) = (int**)malloc((*n) * sizeof(int*));
now became:
mat = malloc(r * sizeof(int*));
This is allocating an array of r integer pointers (which means a matrix of r rows, if each pointer points to a row).
You don't show how this function is called, but presumably it looks something like this:
int n, m;
int **matrix;
reading(&n, &m, &matrix);
So in this context, matrix is defined as a pointer-to-pointer. It can hold the address of the first element of an array of int *, each of which can hold the address of the first element of an array of int.
When &matrix is then passed to this function, you have a pointer-to-pointer-to-pointer, which is what the argument a of reading is. In this context, a contains a pointer to a single int **, specifically matrix in the calling function. By dereferecing a in reading, you're actually accessing matrix in the calling function.
So now getting to this line:
(*a) = (int**)malloc((*n) * sizeof(int*));
This allocates space for an array of *n int * and assigns that to *a, (i.e. matrix in the calling funtion. So now you have an array of int *. Now for this:
for (i = 0; i < *n; i++)
(*a)[i] = (int*)malloc((*m) * sizeof(int));
This loops through the elements of the int * array and assigns to each one a pointer to a memory block big enough for *m int.
So you now effectively have a 2D array of int. Note however that this is not the same as an actual 2D array of int which would be declared as int arr[n][m].
First, you are doing too many different things in a single function, which is making it a bit messy. I suggest that you separate out the logic to get the matrix size from the logic to create the matrix:
void get_size(int *n, int *m) {
printf("n=");
scanf("%d", n);
printf("m=");
scanf("%d", m);
}
int **create_matrix(int n, int m) {
int **matrix = malloc(n * sizeof(int*));
for (int i = 0; i < n; i++)
matrix[i] = malloc(m * sizeof(int));
return matrix;
}
void fill_matrix(int **matrix, int n, int m) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
printf("a[%d][%d]=", i, j);
scanf("%d", [i][j]);
}
}
}
From here it is a lot easier to see what is going on, with fewer *s and &s.
Your matrix is implemented as an array of arrays, so
int **matrix = malloc(n * sizeof(int*));
allocates memory for the outer array, while
matrix[i] = malloc(m * sizeof(int));
allocates memory for each of the inner arrays.
int ***a declares a to be a pointer to a pointer to pointer to an int. The caller is required to have their own int ** and to pass its address to this function. For example, the caller might define int **x; and pass &x to this function for the parameter a. I will use x to refer to the caller’s int **.
(*a) = (int**)malloc((*n) * sizeof(int*)); sets the caller‘s pointer (x) to point to space for *n pointers to int. This is preparation for fabricating a matrix of *n rows—memory will be allocated for each row, and we will have a pointer to that memory, so we need n pointers.
Then these lines:
for (i = 0; i < *n; i++)
(*a)[i] = (int*)malloc((*m) * sizeof(int));
allocate memory for *n rows. The second line allocates memory for an array of m int and sets x[i] to point to the first element of that memory. Note that since a is an int ***, *a is an int **, and (*a)[i] is an int *. Thus, *a points to an array of int * elements.
Finally, these lines:
for (i = 0; i < *n; i++) {
for (j = 0; j < *m; j++) {
printf("a[%d][%d]=", i, j);
scanf("%d", &(*a)[i][j]);
}
}
set each element of the *n by *m array: For each element x[i][j] (referred to as (*a)[i][j], it passes the address of the element (&(*a)[i][j]) to scanf to be set from the input stream.

Using pointers and malloc alone, how to define 2D int array? mine seems doesnt work. (seg fault)

I want to declare 2D-array in .h file without given numbers of COLS nor ROWS (cause they are read somewhere from inside the main() )
I mean I could tried another way of doing this like below
if one of ROWS and COLS is given at the firsthand.
int COLS = 20;
int (*array)[COLS];
array = malloc((*array) * ROWS);
thus I tried like below:
below is 2d.h
int* a;
int** b;
int size;
below is test2d.c, inside int main(){}
read_size() //size value read from some file
a = malloc(sizeof(int) * size);
b = malloc(sizeof(*a) * size);
for(int i=0; i<size; i++){
for(int j=0; j<size; j++){
b[i][j] = i+j;
printf("ok");
}
}
//print all
should be printing all 0112 but the result is segmentation fault.
To allocate a 2D array you need to allocate the 2D pointer b, which you have done. After that you need to allocate memory for b[i] in a for loop as below
// cols and rows are input by user or other parts of program.
int **b;
b = malloc(sizeof(int*) * rows);
for(int i=0; i<rows; i++){
b[i] = malloc(sizeof(int) * cols);
}
The explanation for this is that b is an array of pointers to int. In each element of b you allocate an array of int. This gives you a 2D array.
If you want a rectangular (not jagged array), it's most efficient to allocate all the cells as a single block, then the row pointers can all point into that block:
#include <stdlib.h>
int **make_array(size_t height, size_t width)
{
/* assume this multiplication won't overflow size_t */
int *cells = malloc((sizeof *cells) * height * width);
int **rows = malloc((sizeof *rows) * height);
if (!rows || !cells) {
free(cells);
free(rows);
return 0;
}
/* now populate the array of pointers to rows */
for (size_t row = 0; row < height; ++row) {
rows[row] = cells + width * row;
}
return rows;
}
This also makes deallocation much simpler, as we no longer need a loop:
void free_array(int **a)
{
if (!a) return;
free(a[0]);
free(a);
}

Erros in dynamically allocated array in C

I am trying to dynamically allocate a 2D array, put some values, and print output. However it seems that I am making mistake in getting input to program in atoi() function.
Basically when we assign a static 2D array, we declare it as say int a [3][3]. So 3*3 units if int, that much memory gets allocated. Is same thing holds for allocating dynamic array as well?
Here is my code:
#include<stdio.h>
#include<stdlib.h>
int main(int arg,char* argv)
{
int rows = atoi(argv[1]);
int col = atoi(argv[2]);
int rows =3;
int col=3;
int i,j;
int (*arr)[col] = malloc(sizeof (*arr)*rows);
int *ptr = &(arr[0][0]);
int ct=1;
for (i=0;i<rows;i++)
{
for(j=0;j<col;j++)
{
arr[i][j]=ct;
ct++;
}
}
printf("printing array \n");
for (i=0;i<rows;i++)
{
for(j=0;j<col;j++)
{
printf("%d \t",arr[i][j]);
}
printf("\n");
}
free(arr);
return (0);
}
Program crashes in runtime. Can someone comment?
Try to change the third line to:
int main(int arg,char **argv)
The common method to use dynamic matrices is to use a pointer to pointer to something, and then allocate both "dimensions" dynamically:
int **arr = malloc(sizeof(*arr) * rows);
for (int i = 0; i < rows; ++i)
arr[i] = malloc(sizeof(**arr) * col);
Remember that to free the matrix, you have to free all "rows" in a loop first.
int rows = atoi(argv[1]);
int col = atoi(argv[2]);
int rows =3;
int col=3;
int i,j;
You are defining rows and col twice.... that would never work!
With traditional C, you can only have the array[][] structure for multiple dimension arrays work with compile time constant values. Otherwise, the pointer arithmetic is not correct.
For dynamically sized multi dimensional arrays (those where rows and cols are determined at runtime), you need to do additional pointer arithmetic of this type:
int *a;
int rows=3;
int cols=4;
a = malloc(rows * cols * sizeof(int));
for (int i = 0; i < rows; ++i)
for (int j = 0; j < cols; ++j)
a[i*rows + j] = 1;
free(a);
Alternatively, you can use double indirection and have an array of pointers each pointing to a one dimensional array.
If you are using GCC or any C99 compiler, dynamic calculation of multiple dimension arrays is simplified by using variable length arrays:
// This is your code -- simplified
#include <stdio.h>
int main(int argc, const char * argv[])
{
int rows = atoi(argv[1]);
int col = atoi(argv[2]);
// you can have a rough test of sanity by comparing rows * col * sizeof(int) < SIZE_MAX
int arr[rows][col]; // note the dynamic sizing of arr here
int ct=1;
for (int i=0;i<rows;i++)
for(int j=0;j<col;j++)
arr[i][j]=ct++;
printf("printing array \n");
for (int i=0;i<rows;i++)
{
for(int j=0;j<col;j++)
{
printf("%d \t",arr[i][j]);
}
printf("\n");
}
return 0;
} // arr automatically freed off the stack
With a variable length array ("VLA"), dynamic multiple dimension arrays in C become far easier.
Compare:
void f1(int m, int n)
{
// dynamically declare an array of floats n by m size and fill with 1.0
float *a;
a = malloc(m * n * sizeof(float));
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
a[i*n + j] = 1.0;
free(a);
}
With VLA you can write to do the same:
void f2(int m, int n)
{
// Use VLA to dynamically declare an array of floats n by m size and fill with 1.0
float a[m][n];
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
a[i][j] = 1.0;
}
Be aware that unlike malloc / free VLA's handling of requesting a size larger than what is available on the stack is not as easily detected as using malloc and testing for a NULL pointer. VLA's are essentially automatic variables and have similar ease and restrictions.
VLA's are better used for smaller data structures that would be on the stack anyway. Use the more robust malloc / free with appropriate detection of failure for larger data structures.
If you are not using a fairly recent vintage C compiler that supports C99 -- time to get one.

Dynamic matrix and dynamic values into matrix

This is my code - i init my own values (1 or 0) into a defined matrix.
instead of setting always a hardcoded matrix i want the user to set values and the dimantions of the matrix
scanf("%d %d", &height, &width);
and after building the matrix to initscan his value
scanf("%d", &vall);
Please help me with this i never done something dynamic this way and dont know how to load dynamix matrix with dynamic values straight from the user please show me your syntax for this so i could learn.
printf("How many Row : ");
scanf("%d", &nrow);
rowptr = malloc(sizeof(int) * nrow);
printf("How many Column : ");
scanf("%d", &ncol);
thank you
#include <stdio.h>
#define WIDTH 50
#define HEIGHT 20
void init(int board[][WIDTH], int rows) {
int x, y;
for (y = 0; y < rows; y++)
for (x = 0; x < WIDTH; x++)
board[y][x] = 0;
/* Scatter some live cells: */
board[10][25] = 1;
board[10][26] = 1;
board[10][27] = 1;
board[11][25] = 1;
board[12][26] = 1;
}
You can use malloc() function for this. malloc() takes the number of bytes as parameter and returns a void pointer on success. You'll need to cast it to the pointer of the appropriate data type to use it. Here's an example:
int **board;
scanf("%d %d", &height, &width);
// first allocate memory for pointer to each row
board = (int**) malloc(height * sizeof(int*));
// then allocate memory for each row
for(i = 0; i < height; i++)
board[i] = (int*) malloc(width * sizeof(int));
And when you're done, free up the allocated memory to avoid memory leak. You have to free them in reverse order:
// first free up each row
for(i = 0; i < height; i++)
free(board[i]);
// then free up the pointers to the rows
free(board);
Edit:
For your code, do this:
printf("How many Row : ");
scanf("%d", &nrow);
rowptr = (int**) malloc(sizeof(int) * nrow);
printf("How many Column : ");
scanf("%d", &ncol);
for(i = 0; i < nrow; i++)
rowptr[i] = (int*) malloc(ncol * sizeof(int));
You have to use the malloc() function to assign memory dinamically. It returns a pointer to a block of memory of the requested size. Here's an example:
int size;
int *foo;
printf("How many elements? ");
scanf("%d", &size);
foo = malloc(size * sizeof(int));
// always check if the call succeeded
if(foo == NULL) {
printf("can't allocate memory!");
return;
}
int i;
for(i = 0; i < size; i++) {
printf("enter value for element #%d: ", i + 1);
scanf("%d", &foo[i]);
}
// ...
free(foo); // to avoid memory leaks
free() tells the os that the block you pass in is no longer in use, so it's available for the future.
Now, since you want a matrix, you need a double pointer and you have to call malloc for every "row" (error checking removed for clarity):
int **matrix = malloc(rows * columns * sizeof(int));
int i;
for(i = 0; i < rows; i++)
matrix[i] = malloc(columns * sizeof(int));
To have a solution with a full dynamic arrays of arrays (a 2D matrix with number of rows and columns unknown at compile time), you should use an int ** type to represent your matrix.
int **board = malloc(height * sizeof *board);
for (i = 0; i < height; i++)
board[i] = malloc(width * sizeof **board);
then prototype your functions with an int ** for the board parameter and access your matrix as usual:
int x = board[i][j]; // store in x the element of row i and column j
If you have modern C, say C99, initializing a matrix dimension with variable content is possible. It is called variable length array, VLA. On what concerns your code, you are almost there. Just change your prototypes to something like the following
void init(size_t cols, size_t rows, int board[rows][cols])
such that the bounds come first and are known when you come to the declaration of the matrix.
You could principally allocate such matrices on the stack
int board[rows][cols];
(without initializer) would do, but if your dimension get large you'd risk stack overflow. To declare a matrix on the heap, you could do something like
int (*board)[cols] = malloc(int[rows][cols]);
don't forget to assign initial values to the individual entries board[i][j] and to free the whole matrix at the end of its use.
Edit: seeing all these answers that try to sell you simulations of 2D arrays via pointers to pointers. Don't do such complicated things, just do what the language provides you directly, VLA.

Resources