I have 2D array allocated dynamically using this method:
How do we allocate a 2-D array using One malloc statement
#include <stddef.h>
int main() {
size_t i;
unsigned int nrows=2;
unsigned int ncolumns=3;
int **array; /* Declare this first so we can use it with sizeof. */
const size_t row_pointers_bytes = nrows * sizeof *array;
const size_t row_elements_bytes = ncolumns * sizeof **array;
array = malloc(row_pointers_bytes + nrows * row_elements_bytes);
int * const data = array + nrows;
for(i = 0; i < nrows; i++) {
array[i] = data + i * ncolumns;
printf("%x\n", data + (i * 3));
}
}
I understand that array[0] points to 1st 1D array (of 2D array) and array[1] points to 2nd 1D array, but now how to initialize (and access) others member of this 2D array, for instance a[0][1] can be access like?
array[0] + (char *)1
It would great, if I may ask for some graphical view of it.
The main problem is that you read a lot of harmful answers in that other post. You are making everything needlessly slow and complicated. Instead study Correctly allocating multi-dimensional arrays (which has the requested graphical view as "ASCII art").
Fixed code printing some hex data as example:
#include <stdlib.h> // include this!
#include <stdio.h>
int main()
{
// memory in C is laid out in rows, so ideally use rows as inner index
unsigned int col=4;
unsigned int row=8;
int (*array)[row] = malloc(sizeof(int[col][row]));
int count=0; // some data
for(size_t i=0; i<col; i++)
{
for(size_t j=0; j<row; j++)
{
array[i][j] = count++;
printf("%.2X ", array[i][j]);
}
printf("\n");
}
free(array); // call this!
}
Related
How can I return an array from a function, I am trying to perform (3*3)*(3*1) matrix multiplication using this translation function and how can i get an array out of it.
#include <stdio.h>
#include <math.h>
int* translation(int x, int y, int tx, int ty) {
static int res[3][1] = {0}, xy[3][1] = {{x},{y},{1}};
int tm[3][3] = {{1,0, tx}, {0,1,ty}, {0,0,1}};
for (int i = 0; i<3; i++) {
for (int j = 0; j<3; j++) {
res[i][0] += tm[i][j]*xy[j][0];
}
}
return res;
}
int main()
{
int *arr[3][1];
arr = translation(5, 5);
printf("%d %d %d", arr[0][0], arr[0][1], arr[0][2]);
return 0;
}
"How can I return an array from a function"
You can't.
The language has no such concept.
You'll have to return something including the length to give the user of the function the information. In C the idiomatic approach is to supply a pointer to the function and to get a value (via that pointer) in return:
size_t no_idea;
void function(void *data, &no_idea);
As a user of this function you'd have to read no_idea before judging.
you question is missing a lot of information like what you want to do with your code, the variable named xy isn't defined anywhere in your code, and so on...
but for clarification, if your result matrix is of unknown size, you can wrap your array into a struct, if you don't know what is the struct, you can refer to this small tutorial about struct in c, so your struct maybe look like something like this:
typedef struct Array_t{
size_t arrSize_x;
size_t arrSize_y;
int **arr;
}Array_t;
where arr is your matrix of unknown size which will be created dynamically and arrSize_x, arrSize_y are your matrix dimensions.
so in order to create a matrix of unknow size at compile time , you should create it dynamically in the heap memory using functions like calloc or malloc, although in C99, it allowed created arrays statically of unknown size during compile time but it's not the case with struct as the struct once defined, your array is created and you cannot do something like this:
typedef struct Array_t{
size_t arrSize_x;
size_t arrSize_y;
int arr[arrSize_x][arrSize_y];
}Array_t;
but if the size of the array is known you can do something like this:
typedef struct Array_t{
int arr[3][1];
}Array_t;
to create a dynamic array, you will find in the next example code something like this:
// rows are stored in heap memory and initiated with zeros
res.arr = (int**) calloc(res.arrSize_x, sizeof(int));
// columns are also stored in heap memory and initiated with zeros
for (int i = 0; i < res.arrSize_x; ++i) {
res.arr[i] = (int *) calloc(res.arrSize_y, sizeof(int));
}
where res.arr is a pointer pointing to an array of pointers and the next diagram may simplify my explanation where the next graph expresses the created matrix in heap memory for arr of size 3 x 1:
while if the size is known, so the explanation diagram may look like this:
and when you return, you can either return by value or by reference, but if you are going to return a struct by reference then you should declare it as static.
so you can do something like this (for clarification purposes, size of matrix is unknown):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct Array_t{
size_t arrSize_x;
size_t arrSize_y;
int **arr;
}Array_t;
Array_t translation(int x, int y, int tx, int ty) {
// create a struct holding the array
Array_t res;
res.arrSize_x = 3;
res.arrSize_y = 1;
// rows are stored in heap memory and initiated with zeros
res.arr = (int**) calloc(res.arrSize_x, sizeof(int));
// columns are also stored in heap memory and initiated with zeros
for (int i = 0; i < res.arrSize_x; ++i) {
res.arr[i] = (int *) calloc(res.arrSize_y, sizeof(int));
}
res.arr[0][0] = 1;
res.arr[1][0] = 2;
res.arr[2][0] = 3;
return res;
}
int main()
{
Array_t array;
// 1, 2, 3, 4 are dummy parameters
array = translation(1, 2, 3, 4);
printf("elements are :\n");
for (int i = 0; i < array.arrSize_x; ++i) {
for (int j = 0; j < array.arrSize_y; ++j) {
printf("%d\t", array.arr[i][j]);
}
printf("\n");
}
return 0;
}
and this is the output:
elements are :
1
2
3
but if size of matrix is known then you can do something like this (for clarification purposes, size of matrix is known):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct Array_t{
int arr[3][1];
}Array_t;
Array_t translation(int x, int y, int tx, int ty) {
// create a struct holding the array
Array_t res;
res.arr[0][0] = 1;
res.arr[1][0] = 2;
res.arr[2][0] = 3;
return res;
}
int main()
{
Array_t array;
// 1, 2, 3, 4 are dummy parameters
array = translation(1, 2, 3, 4);
printf("elements are :\n");
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 1; ++j) {
printf("%d\t", array.arr[i][j]);
}
printf("\n");
}
return 0;
}
and this is the ouput:
elements are :
1
2
3
I'm sort of confused between these 2 declarations
int *a;
int (*a)[3]
As I understand it, both of these give us a single pointer pointing to nothing in memory. The 2nd one is shown to be an example of a pointer pointing to an array of 3 ints in memory. But since this memory has not even been allocated, does it make any sense.
To make the pointer point to an array of 3 ints in memory, we need to do a a = (int*)malloc(sizeof(int) * 3). Doing this for the first one AND the second one will both give me a pointer pointing to a memory location where 12 consecutive bytes store my 3 numbers.
So why use int (*a)[3] at all if eventually I have to use malloc ?
So why use int (*a)[3] at all if eventually I have to use malloc ?
It is very useful for variable length arrays when you want to create a real 2d array using dynamic memory:
#include <stdio.h>
#include <stdlib.h>
void *fn_alloc(int rows, int cols)
{
int (*arr)[cols];
int i, j;
arr = malloc(sizeof(int [rows][cols]));
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
arr[i][j] = (i * cols) + j;
}
}
return arr;
}
void fn_print(int rows, int cols, int (*arr)[cols])
{
int i, j;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
printf("\t%d", arr[i][j]);
}
printf("\n");
}
}
int main(void)
{
int rows, cols;
scanf("%d %d", &rows, &cols);
int (*arr)[cols] = fn_alloc(rows, cols);
fn_print(rows, cols, arr);
free(arr);
return 0;
}
In other words, when dynamic memory is involved, your first declaration is useful for pointing to an array of n dimensions while the second one is useful to point to an array of array of n dimensions.
So why use int (*a)[3] at all if eventually I have to use malloc ?
Because in most such cases (dynamically sized 2D matrixes), you should have some abstract data type using flexible array members. This answer is very relevant to your question (which is a near duplicate).
I was wondering how to properly use scanf to fill out a multidimensional array.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
int n; //number of rounds
int* sArray; //multidimensional array that holds the scores of both players
int i;
scanf("%d", &n);
sArray = (int*) calloc (n * 2, sizeof(int));
for(i=0; i<n; i++) {
scanf("%d %d", &sArray[i][1], &sArray[i][2]);
}
return 0;
}
It gives me an error, "Subscripted value is not an array, pointer, or vector." Any help would be much appreciated!
A two dimentional array is defined as follows: int sArray[N][M], but since you wanted to work with the dynamic memory I offer you to take a look at a pointer to pointer at int:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n;
scanf("%d", &n);
int **sArray;
sArray = (int **)malloc(n * sizeof(int *));
int i;
for(i = 0; i < n; i++)
{
sArray[i] = (int *)malloc(2 * sizeof(int));
scanf("%d %d", &sArray[i][1], &sArray[i][2]);
}
return 0;
}
Don't forget to clean-up after you are done with the array.
As mentioned in the commentaries, You don't need to cast the result of malloc if you work with pure c. I did this because my c++ compiler refused to compile it without this cast.
You might need to check errors during a dynamic allocation of the array. Read more here
There are already a lot of good answers here on how to define your dynamic 2D array. But this variant was not yet mentionned, so I put it for the records.
As the last dimension of your array is fixed, you could define your 2D array as follows:
int (*sArray)[2]; //multidimensional array that holds the scores of both players
...
sArray = (int(*)[2]) calloc (n, sizeof(int)*2); // self explaining
In this way, all the elements will be stored contiguously (each n element of the allocated array, is 2 contiguous integers), without the need for an array to arrays.
The rest of your code remains identical. Except that you shoud address sArray[i][0] and ..[1] instead of [1] and [2] and free memory at the end. In C array indexing starts always from 0 and goes to size-1.
Of course, this approach is strictly limited to 2D arrays where the last dimension is fixed.
Live demo with addressing
Usually to fill a bidimensional array you will use two nested for loops.
For example :
int array[2][3] = {0};
for (i = 0; i < 2; i++)
for (k = 0; k < 3; k++)
scanf("%d", &array [i][k]);
You could do this too:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
int n; //number of rounds
int** sArray = malloc(2 * sizeof(int*)); //multidimensional array that holds the scores of both players
scanf("%d", &n);
sArray[0] = (int*)calloc(n , sizeof(int));
sArray[1] = (int*)calloc(n , sizeof(int));
int i;
for (i = 0; i < n; i++) {
scanf("%d %d", &sArray[0][i], &sArray[1][i]);
}
free(sArray[0]);
free(sArray[1]);
free(sArray);
return 0;
}
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.
I am new to C and during my learning I want to return a two dimensional array from a function, so that I can use it in my main program. Can anyone explain me the same with example. Thanks in advance.
It depends how it is implemented. You can either work with just a one-dimensional array where you know the length of each (row) and the next row begins immediately after the previous one. OR, you can have an array of pointers to arrays. The extra cost though is you need to de-reference two pointers to get to one element of data.
// 2D array of data, with just one array
char* get_2d_ex1(int rows, int cols) {
int r, c, idx;
char* p = malloc(rows*cols);
for (r=0; r<rows; r++) {
for (c=0; c<cols; c++) {
idx = r*cols + c; // this is key
p[idx] = c; // put the col# in its place, for example.
}
}
return p;
}
Declare your function as returning a pointer to a pointer. If we use int as an example:
int **samplefunction() {
int** retval = new int*[100];
for (int i = 1; i < 100; i++) {
retval[i] = new int[100];
}
// do stuff here to retval[i][j]
return retval;
}
Here's an example of how you might create, manipulate and free a "2d array":
#include <stdlib.h>
#define ROWS 5
#define COLS 10
int **create_2d_array(size_t rows, size_t cols)
{
size_t i;
int **array = (int**)malloc(rows * sizeof(int*));
for (i = 0; i < rows; i++)
array[i] = (int*)malloc(cols * sizeof(int));
return array;
}
void free_2d_array(int **array, size_t rows, size_t cols)
{
size_t i;
for (i = 0; i < rows; i++)
free(array[i]);
free(array);
}
int main(void)
{
int **array2d = create_2d_array(ROWS, COLS);
/* ... */
array2d[3][4] = 5;
/* ... */
free_2d_array(array2d, ROWS, COLS);
return 0;
}
To create a "2d array"/matrix, all you have to do is create a dynamic array of pointers (in this case int*) of the size of the rows/width:
int **array = (int**)malloc(rows * sizeof(int*));
Then you set each of those pointers to point to a dynamic array of int of the size of the columns/height:
array[i] = (int*)malloc(cols * sizeof(int));
Note that the casts on malloc aren't required, it's just a habit I have.