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.
Related
Can I use
size_t m, n;
scanf ("%zu%zu", &m, &n);
int (*a)[n] = (int (*)[n])calloc (m * n, sizeof (int));
to create a dynamic 2D array in C, whose size of rows and columns can be modified by function realloc during runtime?
Also you can use pointer-to-pointer-to-int and alloc first array for "pointers to lines" and then init all items by allocating memory for "arrays of int".
Example:
#include <stdio.h>
#include <stdlib.h>
int main() {
size_t m, n;
scanf("%zu%zu", &m, &n);
int **a = (int **)calloc(m, sizeof(int*));
size_t i, j;
for (i = 0; i < m; i++) {
a[i] = (int *)calloc(n, sizeof(int));
}
/// Work with array
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
a[i][j] = i+j;
printf("%d ", a[i][j]);
}
printf("\n");
}
return 0;
}
Such approach allows to make realloc later
This record
int (*a)[n] = (int (*)[n])calloc (m * n, sizeof (int));
is correct provided that the compiler supports variable length arrays.
It may be written also like
int (*a)[n] = calloc ( 1, sizeof ( int[m][n] ) );
On the other hand, there is a problem when you will use realloc and the number of columns must be changed. This can result in losing elements in the array in its last row because C memory management functions know nothing about types of objects for which the memory is allocated. They just allocate extents of memory of required sizes.
Otherwise if the compiler does not support variable length arrays you will need to allocate array of pointers and for each pointer an array of integers. This approach is more flexible in sense that you can reallocate separately columns and rows.
Can I create a dynamic 2D array in C like this?
int (*a)[n] = (int (*)[n])calloc (m * n, sizeof (int));
Yes.
Cleaner as int (*a)[n] = calloc(m, sizeof a[0]);
Can I use int (*a)[n] = .... to create a dynamic 2D array in C, whose size of rows and columns can be modified by function realloc during runtime?
No. Once an array size of a is defined, (n in this case), the size can not change.
Instead consider allocating an array of arrays
// Error checking omitted for brevity
int **a2 = malloc(sizeof a2 * rows);
for (r = 0; r < rows; r++) {
a2[r] = malloc(sizeof a2[0] * cols);
}
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.
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);
}
This question already has answers here:
Allocating 2-D array in C
(2 answers)
Closed 8 years ago.
I need to create a two dimensional array. Presently I created it as
int a[100][100]
but I need to allocate the memory dynamically using malloc in C language. I used the code
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int n=6, m=5, i, j;
int **a = malloc(n * sizeof(int *));
for(i = 0; i < m; i++)
a[i] = malloc(m * sizeof(int));
for( i = 1; i <= n; i++ )
{
for( j = 1; j <= m; j++ )
{
scanf("%d %d",&a[i][j]);
}
}
return 0;
}
but now while inputting the elements into the array it shows SEGMENTATION ERROR.
You say in the comments that n is the number of rows. So you need to allocate n rows each of length m. Therefore, the second for loop condition should be i < n. Also, you should check the return value of malloc for NULL in case it fails to allocate memory. I suggest the following change -
long long **a = malloc(n * sizeof(*a));
for(i = 0; i < n; i++)
a[i] = malloc(m * sizeof(*a[i]));
Please note that a multi-dimensional array is not a fundamentally new type. It's simply an array of elements where each element itself is an array (for a 2D array), an array of arrays (for a 3D) array and so on. If you are using C99, you can allocate your array cleanly and succinctly as
int nrow = 4; // number of rows
int ncol = 8; // number of columns
// define arr to be a pointer to an array of ncol ints, i.e.,
// arr is a pointer to an object of type (int[ncol])
int (*arr)[ncol] = malloc(sizeof(int[nrow][ncol]));
// check the result of malloc for NULL
if(arr == NULL) {
printf("malloc failed to allocate memory\n");
// handle it
}
// do stuff with arr
for(int i = 0; i < nrow; i++)
for(int j = 0; j < ncol; j++)
arr[i][j] = i + j;
// after you are done with arr
free(arr);
You should also go through this - How do I work with dynamic multi-dimensional arrays in C?
You have three errors: The first is that you allocate only 5 secondary arrays, but in the input you loop over 6 of them.
The second problem is that array indices are zero-based, i.e. the index start at zero and goes to the size minus one.
The third problem is that you scan for two numbers (why?), but you provide only one destination pointer to scanf.
you just need
long *a = malloc(100*100*sizeof(long));
if you want one single big block of memory.
if you want an array of long* pointers and then each array to be in a separate block of memory go like this:
long **a = malloc(100*sizeof(long*));
for (i=0; i<100; i++) {
a[i] = malloc(100*sizeof(long));
}
This creates 1 array of long* pointers, and then 1 array of 100 longs of each pointer, but I'm not sure now if you say a[10][15] for example if it would calculate position of the element as if its a continuous block. Check that out. :)
If you have C99 use Variable Length Array
#include <stdio.h>
#include <stdlib.h>
int main(void) {
unsigned rows, cols;
printf("Enter rows and columns: ");
fflush(stdout);
scanf("%u%u", &rows, &cols);
int (*a)[cols]; // pointer to VLA
a = malloc(rows * cols * sizeof a[0][0]);
if (a) {
for (unsigned r = 0; r < rows; r++) {
for (unsigned c = 0; c < cols; c++) {
a[r][c] = r*c;
}
}
printf("the element at [4, 2] is %d\n", a[4][2]);
free(a);
}
return 0;
}
Otherwise, you need to calculate the indexing manually.
There are many problems in your code
First, you need long long a[100][100] but you only allocate enough space for ints
a[i] = malloc(m * sizeof(int));
You're also accessing arrays out-of-bound. Indexes start from 0 to array_length-1.
Another problem is that you scanf 2 int values but only provide the address for 1.
scanf("%d %d",&a[i][j]);
You can allocate a 100-element array of pointers, each points to an array of another 100-element array but that's not good because it takes time to do 100 mallocs, and the resulting memory most probably isn't contiguous, which makes it cache unfriendly. There are also a small memory overhead too because the memory allocator must round it up to the nearest block size and this is most probably powers of 2, which may be large as you allocate more and more elements in the first dimension.
You should declare a 1D array of size 100*100 instead. This will be much faster and improve cache coherency. To get the element at a[i][j] just do a[i*WIDTH + j]
long long* a = malloc(WIDTH*HEIGHT*sizeof(long long));
for (i = 0; i < WIDTH*HEIGHT; i++)
{
scanf("%lld ",&a[i]);
}
for (i = 0; i < HEIGHT; i++)
{
for (j = 0; j < WIDTH; j++)
{
printf("%lld ", a[i*WIDTH + j]);
}
printf("\n");
}
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.