I want to have a large 2 dimensional array such like
int myArray[10000][2];
I was told that the array built in such way is not appropriate, and should use malloc to build in heap. Could someone show me how to accomplish this? thanks!
#include <stdlib.h>
//alloc
int **vv = malloc(2 * sizeof(int *));
for(int i = 0; i < 2; i++)
vv[i] = malloc(10000 * sizeof(int));
//free
for(int i = 0; i < 2; i++)
free(vv[i]);
free(vv);
Related
I am desperately trying to free a 2d int array and can't manage to do so.
I guess there's something wrong when i intialize the array?
Could you please help me out?
int rows = 2;
int cols = 3;
int *mfields = (int *) malloc(sizeof(int) * rows * cols);
int **matrix = (int **) malloc(sizeof(int *) * rows);
for (int i = 0; i < rows; i++) {
matrix[i] = mfields + i * cols;
for(int j=0; j<rows;j++) {
matrix[i][j] = (i+1)*(j+1);
}
}
for (int i = 0; i < rows; i++) {
free((matrix[i]));
}
free(matrix);
Thanks in advance,
Christian
Two chunks of memory are allocated:
int *mfields = (int *) malloc(sizeof(int) * rows * cols);
int **matrix = (int **) malloc(sizeof(int *) * rows);
and therefore two chunks of memory should be freed:
free(matrix);
free(mfields);
Freeing multiple chunks of memory, as this loop does:
for (int i = 0; i < rows; i++) {
free((matrix[i]));
is incorrect, as it passes addresses to free that were never returned from malloc.
Generally, it is not good to implement matrices as pointers-to-pointers. This prevents the processor from doing load prediction and impairs performance. If the C implementation(s) that will be used with the code support variable length arrays, then it is preferable to simply allocate one chunk of memory:
int (*matrix)[cols] = malloc(rows * sizeof *matrix);
If variable length array support is not available, then a program should allocate one chunk of memory and use manual calculations to address array elements. While this is may be more work for the programmer, it is better for performance:
int *matrix = malloc(rows * cols * sizeof *matrix);
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
matrix[i*cols + j] = (i+1) * (j+1);
I'm trying to create a dynamic array of arrays. So, for example, let's look at Pascal's Triangle:
1
11
121
1331
14641
...
...
This is basically an array of length N, that has at each index an array of i+1.
How exactly do we set that up?
I've tried a little bit using pointers.
I set up an array of pointers like such:
int *arr[N];
Then I need a pointer i to point to an array of i+1, so I did:
int *i = 0;
for(int j = 0; j < N; j++){
int numArr[j+1];
arr[*i] = numArr;
*i++;
}
Am I going the right direction for this? Because I believe I'm supposed to allocate memory for this as I must use free() later. Would I use malloc() for each array initialization?
The code could be made extremely simple, if you know what you're doing:
int *arr = malloc(N * sizeof(int*));
int i;
for (i = 0; i < N; ++i) {
arr[i] = malloc(sizeof(int) * (i + 1));
}
Of course, you'll need corresponding calls to free() further down the line, like this:
for (i = 0; i < N; ++i) {
free(arr[i]);
}
free(arr);
I am trying to solve a Leetcode problem in C.
https://leetcode.com/problems/pascals-triangle/description/
This is my solution to the problem.
I don't think there's an issue with the solution but dynamically allocating memory for a 2D array is getting very complex. Can someone please help me figure out how to correctly allocate memory dynamically to a 2D array. Updated the code based on BLUEPIXY suggestions, I still seem to be getting runtime error.
/**
* Return an array of arrays.
* The sizes of the arrays are returned as *columnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** generate(int numRows, int** columnSizes) {
int i=0,j=0,numColumns =2;
columnSizes = (int **)malloc(numRows * sizeof(int *));
for (i=0; i<numRows; i++)
columnSizes[i] = (int *)malloc( sizeof(int));
int **returnArray = (int **)malloc(numRows * sizeof(int *));
for (i=0; i<numRows; i++)
returnArray[i] = (int *)malloc((i+1) * sizeof(int));
returnArray[0][0] = 1;
*columnSizes =1;
for(i=1;i<numRows;i++)
{
for(j=0;j<numColumns;j++)
{
if(j==0 )
columnSizes[i][j] = returnArray[i-1][j];
else if(j==(numColumns-1))
columnSizes[i][j] = returnArray[i-1][j-1];
else
returnArray[i][j] = returnArray[i-1][j-1] + returnArray[i-1][j];
numColumns++;
}
*(columnSizes+i) = numColumns-1;
}
return returnArray;
}
Problems of new version
(1)
columnSizes = (int **)malloc(numRows * sizeof(int *));
for (i=0; i<numRows; i++)
columnSizes[i] = (int *)malloc( sizeof(int));
should be
*columnSizes = malloc(numRows * sizeof(int));
(※ it is not necessary to cast from void * in C).
(2)
*columnSizes =1;//type of `*columnSizes` is `int *`
should be
**columnSizes = 1;//meant columnSizes[0] = 1; at caller side (main)
(3)
columnSizes[i][j] = returnArray[i-1][j];
...
columnSizes[i][j] = returnArray[i-1][j-1];
should be
returnArray[i][j] = returnArray[i-1][j];
...
returnArray[i][j] = returnArray[i-1][j-1];
because this is typo.
(4)
numColumns++; move to after for(j=0;j<numColumns;j++){ }
(5)
*(columnSizes+i) = numColumns-1;
should be
*(*columnSizes+i) = numColumns-1;//For reasons similar to (2)
The whole fix code:
int** generate(int numRows, int** columnSizes) {
int i=0,j=0,numColumns =2;
*columnSizes = malloc(numRows * sizeof(int));
int **returnArray = (int **)malloc(numRows * sizeof(int *));
for (i=0; i<numRows; i++)
returnArray[i] = (int *)malloc((i+1) * sizeof(int));
returnArray[0][0] = 1;
**columnSizes = 1;
for(i=1;i<numRows;i++)
{
for(j=0;j<numColumns;j++)
{
if(j==0 )
returnArray[i][j] = returnArray[i-1][j];
else if(j==(numColumns-1))
returnArray[i][j] = returnArray[i-1][j-1];
else
returnArray[i][j] = returnArray[i-1][j-1] + returnArray[i-1][j];
}
numColumns++;
*(*columnSizes+i) = numColumns-1;
}
return returnArray;
}
Just do this
int *arr = (int *)malloc(r * c * sizeof(int));
and access the elements like this
int i, j, count = 0;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
*(arr + i*c + j) = ++count;
OR
If you have the pointer to the pointer, then you get get some help from this code
int main()
{
int i,j;
int **p;
(p)=(int**)malloc(5*sizeof(int*));
for(i=0;i<5;i++)
*(p+i)=(int*)malloc(4*sizeof(int));
for(i=0;i<5;i++)
for(j=0;j<4;j++)
p[i][j]=2;
for(i=0;i<5;i++)
for(j=0;j<4;j++)
printf("%d",p[i][j]);
}
If all you have to do for your programming exercise is print out the results, why bother with any storage at all? Just use the solution here.
How to efficiently calculate a row in pascal's triangle?
Regarding multi-dimensional arrays and C, there is no native support for such a thing. So you have to build your own using one or more 1-D blocks of storage and tricks to index into that storage.
The simplest thing, which #tanuj-yadav suggested works fine for most 2-d arrays is just allocate a nXm-length block of storage and do very simple index arithmetic arr[i*c+j].
The other common approach is arrays of arrays (aka ragged arrays). Which is just like a list of lists, and are naively done with a malloc on each row (or column).
I have an integer variable x that I need to use to make two 2D arrays but I get an error of "cannot allocate an array of constant size 0". After doing some research I apparently need to use malloc but I have no idea how to apply it to my currently situation.
My two arrays I need:
int firMat[x][5];
int secMat[5][x];
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int x = 2;
int **firMat;//int firMat[x][5];
int **secMat;//secMat[5][x];
int i;
firMat = malloc(x * sizeof(int*));
for(i = 0; i< x; ++i)
firMat[i] = malloc(5 * sizeof(int));
secMat = malloc(5 * sizeof(int*));
for(i = 0; i< 5; ++i)
secMat[i] = malloc(x * sizeof(int));
//do stuff E.g. fir[2][1] = 21;
//release E.g.
//for(i = 0; i< x; ++i)
// free(firMat[i]);
//free(firMat);
return 0;
}
If you're using C99, this will work. It will create a "variable-length array", sadly VLAs have been reduced to "optional" in C11.
To use malloc for this, typically I'd abandon the double-array notation, and treat the memory as a flat one-dimensional array, then array[i][j] becomes ptr[ i*cols + j ].
Try to initialize x like in the example below
#define x 2 //outside the function
and then use x like this
int firMat[x][5];
int secMat[5][x];
I am experimenting to set up two arrays, let's say array myflags_init and array tripleP; both arrays are two dimenstional, because tripleP is an array of pointers that point to the corresponding index in array myflags_init. Below is my code, and the compiling works fine. I would like to discuss whether this makes sense, as the syntax is a bit crazy to me (e.g. int **tripleP[2] for declaring the two-dimenstional array tripleP of int pointers).
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int m;
for (m = 0; m < 20; m++)
{
int *myflags_init[2];
myflags_init[0] = (int *) calloc(2, sizeof(int));
myflags_init[1] = (int *) calloc(2, sizeof(int));
int r, k;
for (r = 0; r < 2; r++)
{
for (k = 0; k < 10; k++)
{
myflags_init[r][k] = 0; /* initialize the two-d array to 0 */
}
}
int false_num = 0;
int **tripleP[2];
tripleP[0] = (int **) calloc(10, sizeof(int **));
tripleP[1] = (int **) calloc(10, sizeof(int **));
for (r = 0; r < 2; r++)
{
for (k = 0; k < 10; k++)
{
tripleP[r][k] = &myflags_init[r][k]; /* tripleP pointers point to the corresponding index in myflags_init */
}
}
}
return 0;
}
int **tripleP[2];
tripleP[0] = (int **) calloc(10, sizeof(int **));
tripleP[1] = (int **) calloc(10, sizeof(int **));
That works, but shouldn't be written like this. You want to allocate an array of int*, not int**. However it just so happens that both types have the same size (they are both pointers) and thus this will work anyway. But for clarity replace it with this:
int **tripleP[2];
tripleP[0] = (int **) calloc(10, sizeof(int *));
tripleP[1] = (int **) calloc(10, sizeof(int *));
Also the initialization of myflags_init[0] and myflags_init[1] is wrong, because you allocated for 2 elements for each, but try to initialize 10 of them:
myflags_init[0] = (int *) calloc(2, sizeof(int));
myflags_init[1] = (int *) calloc(2, sizeof(int));
//...
for (k = 0; k < 10; k++)
Also you don't need to set them manually to zero. That is exactly what calloc already does for you (in contrast to malloc).
And the outer for-loop seems rather pointless, not to mention the memory leak, because you keep allocating new memory but never call free.