I have a struct[4] with inside a pointer.
I have to malloc this pointer for all the 4 structs
//Here a simplification of my code that produces the same error:
typedef struct{
int *val;
}test_T;
void testAllocSingle(test_T *in){
in->val = (int *)calloc(10, sizeof(int));
}
void testAlloc(test_T *in){
int i = 0;
for (i=0; i<4; i++){
testAllocSingle(&(in[i]));
}
}
void main(void){
test_T a[4];
test_T b[4];
testAlloc(a);
testAlloc(b);
memcpy(b, a, 4*10*sizeof(int));
//FATAL RUN-TIME ERROR: Array argument too small (16 bytes). Argument must contain at least 160 bytes (160 elements).
}
My allocated array is not visible to main.
I'm doing something wrong in passing variables, can anyone tell me where?
Thanks
It's not clear what you're trying to copy, but 4 * 10 * sizeof(int) is not correct in any case. You haven't allocated any single contiguous block that size.
If you want to copy just the array of structs, which just copies the pointers to the array, it's:
memcpy(b, a, 4 * sizeof(test_t));
Note that this causes a memory leak, because you never freed the memory that was allocated in b.
If you want to copy each of the arrays of ints, it's
for (int i = 0; i < 4; i++) {
memcpy(b[i].val, a[i].val, 10 * sizeof(int));
}
This doesn't leak anything, because it's just copying the integers in the arrays, not changing the pointers.
You're calculating size of a and b incorrectly. a and b are 4-elements array of test_T, each of test_T has a pointer to int array. a and b are not contiguous memory with size 4 * 10 * sizeof(int).
You might need instead:
memcpy(b, a, sizeof(a));
Another easiest way is copy with for() instead of memcpy to avoid confusion,
for(i=0;i<4;i++){
b[i] = a[i];
}
The data structures you have before memcpy() look like this in RAM:
Each of the rectangles is a continous block of memory. It can be in any place, not necessarily in a special order, and not in adjacent places.
When you do
b[i] = a[i];
then the storage pointed to by b[i] will be "leaked", that means you lose the reference to it and you can't free it. Both b[i] and a[i] will point to the same array of 10 ints.
When you do
memcpy(b, a, sizeof a);
then all storage pointed to by b[0] to b[3] will be leaked.
To copy all ints from a to b, you could use #Barmar's loop, or this one:
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 10; j++) {
b[i].val[j] = a[i].val[j];
}
}
thank you all for the answers.
Maybe I simplified this example too much.
Unfortunately, there are many other variables in the structure in question
An example closer to reality can be this:
#define MALLOC_SIZE (10) //in the original code is a variable
typedef struct{
int size;
int x;
double y;
char z[32];
int *val;
}test_T;
void setSize(test_T *in){
int i = 0;
for (i=0; i<4; i++){
in[i].size = 0;
in[i].size += sizeof(int);//size
in[i].size += sizeof(int);//x
in[i].size += sizeof(double);//y
in[i].size += (sizeof(char)*32);//z
in[i].size += (sizeof(int)*MALLOC_SIZE);
}
}
void testAllocSingle(test_T *in){
in->val = (int *)calloc(MALLOC_SIZE, sizeof(int));
}
void testAlloc(test_T *in){
int i = 0;
for (i=0; i<4; i++){
testAllocSingle(&(in[i]));
}
}
int main(void){
int tot_size = 0;
test_T a[4];
test_T b[4];
testAlloc(a);
testAlloc(b);
setSize(a);
tot_size = a[0].size + a[1].size + a[2].size + a[3].size;
memcpy(b, a, tot_size);
//FATAL RUN-TIME ERROR: Array argument too small (16 bytes). Argument must contain at least 160 bytes (160 elements).
return 0;
}
Copying everything "manually" remains possible but more inconvenient.
The strange thing is that I only have the problem if I compile and execute the code with NI CVI.
If I compile and execute the code with Eclipse+MinGW I haven't this error
Related
I dynamically allocated memory for 3D array of pointers. My question is how many pointers do I have? I mean, do I have X·Y number of pointers pointing to an array of double or X·Y·Z pointers pointing to a double element or is there another variant?
double*** arr;
arr = (double***)calloc(X, sizeof(double));
for (int i = 0; i < X; ++i) {
*(arr + i) = (double**)calloc(Y, sizeof(double));
for (int k = 0; k < Y; ++k) {
*(*(arr+i) + k) = (double*)calloc(Z, sizeof(double));
}
}
The code you apparently intended to write would start:
double ***arr = calloc(X, sizeof *arr);
Notes:
Here we define one pointer, arr, and set it to point to memory provided by calloc.
Using sizeof (double) with this is wrong; arr is going to point to things of type double **, so we want the size of that. The sizeof operator accepts either types in parentheses or objects. So we can write sizeof *arr to mean “the size of a thing that arr will point to”. This always gets the right size for whatever arr points to; we never have to figure out the type.
There is no need to use calloc if we are going to assign values to all of the elements. We can use just double ***arr = malloc(X * sizeof *arr);.
In C, there is no need to cast the return value of calloc or malloc. Its type is void *, and the compiler will automatically convert that to whatever pointer type we assign it to. If the compiler complains, you are probably using a C++ compiler, not a C compiler, and the rules are different.
You should check the return value from calloc or malloc in case not enough memory was available. For brevity, I omit showing the code for that.
Then the code would continue:
for (ptrdiff_t i = 0; i < X; ++i)
{
arr[i] = calloc(Y, sizeof *arr[i]);
…
}
Notes:
Here we assign values to the X pointers that arr points to.
ptrdiff_t is defined in stddef.h. You should generally use it for array indices, unless there is a reason to use another type.
arr[i] is equivalent to *(arr + i) but is generally easier for humans to read and think about.
As before sizeof *arr[i] automatically gives us the right size for the pointer we are setting, arr[i].
Finally, the … in there is:
for (ptrdiff_t k = 0; k < Y; ++k)
arr[i][k] = calloc(Z, sizeof *arr[i][k]);
Notes:
Here we assign values to the Y pointers that arr[i] points to, and this loop is inside the loop on i that executes X times, so this code assigns XY pointers in total.
So the answer to your question is we have 1 + X + XY pointers.
Nobody producing good commercial code uses this. Using pointers-to-pointers-to-pointers is bad for the hardware (meaning inefficient in performance) because the processor generally cannot predict where a pointer points to until it fetches it. Accessing some member of your array, arr[i][j][k], requires loading three pointers from memory.
In most C implementations, you can simply allocate a three-dimensional array:
double (*arr)[Y][Z] = calloc(X, sizeof *arr);
With this, when you access arr[i][j][k], the compiler will calculate the address (as, in effect, arr + (i*Y + j)*Z + k). Although that involves several multiplications and additions, they are fairly simple for modern processors and are likely as fast or faster than fetching pointers from memory and they leave the processor’s load-store unit free to fetch the actual array data. Also, when you are using the same i and/or j repeatedly, the compiler likely generates code that keeps i*Y and/or (i*Y + j)*Z around for multiple uses without recalculating them.
Well, short answer is: it is not known.
As a classic example, keep in mind the main() prototype
int main( int argc, char** argv);
argc keeps the number of pointers. Without it we do not know how many they are. The system builds the array argv, gently updates argc with the value and then launches the program.
Back to your array
double*** arr;
All you know is that
arr is a pointer.
*arr is double**, also a pointer
**arr is double*, also a pointer
***arr is a double.
What you will get in code depends on how you build this. A common way if you need an array of arrays and things like that is to mimic the system and use a few unsigned and wrap them all with the pointers into a struct like
typedef struct
{
int n_planes;
int n_rows;
int n_columns;
double*** array;
} Cube;
A CSV file for example is char ** **, a sheet workbook is char ** ** ** and it is a bit scary, but works. For each ** a counter is needed, as said above about main()
A C example
The code below uses arr, declared as double***, to
store a pointer to a pointer to a pointer to a double
prints the value using the 3 pointers
then uses arr again to build a cube of X*Y*Z doubles, using a bit of math to set values to 9XY9.Z9
the program uses 2, 3 and 4 for a total of 24 values
lists the full array
list the first and the very last element, arr[0][0][0] and arr[X-1][Y-1][Z-1]
frees the whole thing in reverse order
The code
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int n_planes;
int n_rows;
int n_columns;
double*** array;
} Cube;
int print_array(double***, int, int, int);
int main(void)
{
double sample = 20.21;
double* pDouble = &sample;
double** ppDouble = &pDouble;
double*** arr = &ppDouble;
printf("***arr is %.2ff\n", ***arr);
printf("original double is %.2ff\n", sample);
printf("*pDouble is %.2ff\n", *pDouble);
printf("**ppDouble is %.2ff\n", **ppDouble);
// but we can build a cube of XxYxZ doubles for arr
int X = 2;
int Y = 3;
int Z = 4; // 24 elements
arr = (double***)malloc(X * sizeof(double**));
// now each arr[i] must point to an array of double**
for (int i = 0; i < X; i += 1)
{
arr[i] = (double**)malloc(Y * sizeof(double*));
for (int j = 0; j < Y; j += 1)
{
arr[i][j] = (double*)malloc(Z * sizeof(double));
for (int k = 0; k < Z; k += 1)
{
arr[i][j][k] = (100. * i) + (10. * j) + (.1 * k) + 9009.09;
}
}
}
print_array(arr, X, Y, Z);
printf("\n\
Test: first element is arr[%d][%d[%d] = %6.2f (9XY9.Z9)\n\
last element is arr[%d][%d[%d] = %6.2f (9XY9.Z9)\n",
0, 0, 0, arr[0][0][0],
(X-1), (Y-1), (Z-1), arr[X-1][Y-1][Z-1]
);
// now to free this monster
for (int x = 0; x < X; x += 1)
{
for (int y = 0; y < Y; y += 1)
{
free(arr[x][y]); // the Z rows
}
free(arr[x]); // the plane Y
}
free(arr); // the initial pointer;
return 0;
}; // main()
int print_array(double*** block, int I, int J, int K)
{
for (int a = 0; a < I; a += 1)
{
printf("\nPlane %d\n\n", a);
for (int b = 0; b < J; b += 1)
{
for (int c = 0; c < K; c += 1)
{
printf("%6.2f ", block[a][b][c]);
}
printf("\n");
}
}
return 0;
}; // print_array()
The output
***arr is 20.21f
original double is 20.21f
*pDouble is 20.21f
**ppDouble is 20.21f
Plane 0
9009.09 9009.19 9009.29 9009.39
9019.09 9019.19 9019.29 9019.39
9029.09 9029.19 9029.29 9029.39
Plane 1
9109.09 9109.19 9109.29 9109.39
9119.09 9119.19 9119.29 9119.39
9129.09 9129.19 9129.29 9129.39
Test: first element is arr[0][0[0] = 9009.09 (9XY9.Z9)
last element is arr[1][2[3] = 9129.39 (9XY9.Z9)
I've a problem about deallocating memory using free() in C.
My program generates a random genealogic tree using a matrix. This matrix can be very huge depending on the number of family members. The program seemed to work fine until I decided to generate more than one tree. I noticed that generating about 100 trees causes my 8GB RAM to fill! I'm sure I can make a better code to reduce the demand of memory, but my problem remains.
I use free() to deallocate memory and there's no error. I installed Valgrind to se what's happening and it says that about 100 million byte per tree are definitely lost. This means that free() doesn't work fine. I don't now where is the problem. I link some functions that I think are correlated to the problem.
typedef struct{
int f_id;
char f_name[L_NAMES];
int generations;
int n_members;
type_people *members;
int_mtx *mtx;
}type_family;
The struct above is for the family.
typedef struct temp{
int p_id;
char name[L_NAMES];
char f_name[L_NAMES];
int generation;
int n_sons;
struct temp **sons;
int f_id;
int sex;
int age;
}type_people;
This is for the members.
typedef struct{
int i;
int j;
int **val;
}int_mtx;
And the matrix.
In the main i call the function to initialize the tree:
type_family *family_a;
family_a = malloc(sizeof(type_family));
family_a = init_family_n_gen(family_a, 6);
This is the frist part of init_family_n_gen():
type_family *init_family_n_gen(type_family *family, int n){
...
family->members = malloc(max_people * sizeof(type_people));
family->mtx = mtxcalloc(family->mtx, max_people, max_people - 1);
...
This code is for mtxcalloc that initializes the matrix:
int_mtx *mtxcalloc(int_mtx *mtx, int i, int j){
mtx = malloc(sizeof(int_mtx));
mtx->i = i;
mtx->j = j;
mtx->val = malloc(i * sizeof(int *));
for(int a = 0; a < i; a++){
mtx->val[a] = malloc(j * sizeof(int));
for(int b = 0; b < j; b++){
mtx->val[a][b] = 0;
}
}
return mtx;
}
And to conclude the code to deallocate the family:
void free_family(type_family *family){
for(int m = 0; m < family->n_members; m++){
if(family->members[m].n_sons != 0){
free(family->members[m].sons);
}
}
mtxfree(family->mtx);
free(family->members);
}
And the one to deallocate the matrix:
void mtxfree(int_mtx *mtx){
for(int i = 0; i < mtx->i; i++){
free(mtx->val[i]);
}
free(mtx->val);
free(mtx);
}
Screen capture of Valgrind output
So I call the free_family(family_a) every time i need to regenerate the family but the memory still increases. (In the photo above the number of byte become 1 billion if i regenerate the family for 50 times).
Thanks for the support!
EDITED
I made a minimal reproducible example that emulates my original code. The structs and variables are the same but I changed the functions according to Weather Vane: they are all void and I pass them the double **.
The init_family_n_gen becomes:
void init_family(type_family **f){
type_family *family = malloc(sizeof(type_family));
family->members = malloc(100 * sizeof(type_people));
for(int m = 0; m < 100; m++){
family->members[m].n_sons = 0;
}
mtxcalloc(&family->mtx, 100, 99);
family->mtx->val[0][1] = 7;
family->mtx->val[9][8] = 1;
mtxrealloc(&family->mtx, 5, 4);
*f = family;
}
The main is:
type_family *family_a;
init_family(&family_a);
free_family(&family_a);
The only thing I added is this function(Is the code right?):
void mtxrealloc(int_mtx **mtx, int i, int j){
(*mtx)->i = i;
(*mtx)->j = j;
(*mtx)->val = realloc((*mtx)->val, (*mtx)->i * sizeof(int *));
for(int a = 0; a < (*mtx)->i; a++){
(*mtx)->val[a] = realloc((*mtx)->val[a], (*mtx)->j * sizeof(int));
}
}
I noticed that the problem occours when i use the realloc function and i can't figure why. I link the images of Valgrind with and without the function mtxrealloc. (I see that there is aslo a 48 byte leak...).
Valgrind with realloc
Valgrind without realloc
Thanks again for your support!
This:
init_family(&family_a);
Causes this code from mtxcalloc to execute:
mtx->val = malloc(i * sizeof(int *));
for(int a = 0; a < i; a++){
mtx->val[a] = malloc(j * sizeof(int));
for(int b = 0; b < j; b++){
mtx->val[a][b] = 0;
}
}
, with i, j = 100, 99. That is, you allocate space for 100 pointers, and for each one, you allocate space for 99 ints. These are then accessible via family_a->mtx.
Very shortly thereafter, you make this call:
mtxrealloc(&family->mtx, 5, 4);
, which does this, among other things:
(*mtx)->val = realloc((*mtx)->val, (*mtx)->i * sizeof(int *));
That loses all the pointers (*mtx)->val[5] through (*mtx)->val[99], each of which is the sole pointer to allocated space sufficient for 99 ints. Overall, sufficient space for 9405 ints is leaked before you even perform any computations with the object you are preparing.
It is unclear why you overallocate, just to immediately (attempt to) free the excess, but perhaps that's an artifact of your code simplification. It would be much better to come up with a way to determine how much space you need in advance, and then allocate only that much in the first place. But if you do need to reallocate this particular data, then you need to first free each of the (*mtx)->val[x] that will be lost. Of course, if you were going to reallocate larger, then you would need to allocate / reallocate all of the (*mtx)->val[x].
I'm trying to create a shared memory for IPC. I want to put a structure with dynamic 2D array in it into the shared memory. Here is the structure.
/* struct with 2 2D arrays. */
struct _test {
uint16_t **A;
uint16_t **B;
} test;
I know that a double pointer is not actually a 2D array and I should use a pointer to array like int (*ptr)[3], but the problem is that I can only get the size of the 2D array during runtime. So I have to declare the 2D array this way(at least what I know of).
Then I calculate the size of those two arrays in run time, say they both are 2x2 arrays, which takes 16 bytes(uint16_t is 2 byte). So I did this:
#include <sys/ipc.h>
#include <sys/shm.h>
#include <memory.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
size_t size = 16; //size of two uint16_t 2D arrays.
key_t key;
key = ftok("dev/null", 1);
int s_shm_id = shmget(key, size, IPC_CREAT|0600); //get 16 bytes of shared memory.
test *shm = (test*)shmat(s_shm_id,(const void*)0,0); //attach it.
//I want pointers in this struct to point at shared memory.
test *ptr = malloc(sizeof(test));
//Array A starts at the beginning of shared memory.
ptr -> A = (uint16_t **)shm; //My main confusion is here. Is this right?
int i;
for(i=0; i<2; i++)
ptr->A[i] =(uint16_t *)((uint16_t *)ptr->A + i*2);
//Array B starts right after A.
ptr -> B = ptr -> A[i-1] + 2;
for(i=0; i<2; i++)
ptr -> B[i] = (uint16_t *)((uint16_t *)ptr->B + i*2);
}
I understand this is basically wrong, I got segfault, but how? What a pointer needs is an address to point at, since I have already created a space(using shmget), why can't I make a pointer to point at it? Thanks for any feed back in advance!
What you are after are "jagged" or "scattered" arrays, not "linear" arrays. A scattered 2D-array in fact is not one array, but 1+N arrays, with N being the dimension of the 2D-matrix you are after.
The code you show misses to allocated this 1 array inside "1+N".
Assuming you successfully allocated enough memory to hold two 2D arrays with dimension N of uint16_t, that is 2 * N*N * sizeof (uint16_t) bytes, then the code to prepare the access to this memory might look like this (error checking left out for readability):
void * p = ... /* Allocate memory here; does not necessarily needs to be SHM. */
uint16_t ** A = malloc(N * sizeof *A);
for (size_t i = 0; i < N; ++i)
{
A[i] = ((uint16_t*) p) + i*N;
}
uint16_t ** B = malloc(N * sizeof *B);
for (size_t i = N; i < 2*N; ++i)
{
B[i - N] = ((uint16_t*) p) + i*N;
}
/* Access A[0 .. N-1][0 .. N-1] and B[0 .. N-1][0 .. N-1] here ... */
Placing A and B inside a struct which in turn is allocated dynamically is left to you as an exercise.
Accessing the arrays' elements is done straight forward: A[0][0] accesses the 1st array's 1st row's 1st element.
For clarity the same code for NxM arrays
uint16_t ** A = malloc(N * sizeof *A);
for (size_t i = 0; i < N; ++i)
{
A[i] = ((uint16_t*) p) + i*M;
}
uint16_t ** B = malloc(N * sizeof *B);
for (size_t i = N; i < 2*N; ++i)
{
B[i - N] = ((uint16_t*) p) + i*M;
}
I don't understand why this works:
void main() {
int * b;
b = (int *)malloc(sizeof(int));
*b = 1;
printf("*b = %d\n", *b);
}
while this does not (gets segmentation fault for the malloc()):
void main() {
int ** a;
int i;
for (i = 0; i<= 3; i++) {
a[i] = (int*)malloc(sizeof(int));
*(a[i]) = i;
printf("*a[%d] = %d\n", i, *(a[i]));
}
}
since I find a[i] is just like b in the first example.
BTW, a[i] is equal to *(a+i), right?
You need to allocate memory for a first, so that you can access its members as a[i].
So if you want to allocate for 4 int * do
a = malloc(sizeof(int *) * 4);
for (i = 0; i<= 3; i++) {
...
}
or define it as array of integer pointers as
int *a[4];
a is a 2 dimensional pointer, you have to allocate both dimension.
b is a 1 dimensional pointer, you have to allocate only one dimension and that's what you're doing with
b = (int *)malloc(sizeof(int));
So in order the second example to work you have to allocate the space for the pointer of pointer
void main() {
int ** a;
int i;
a = (int**)malloc(4*sizeof(int*));
for (i = 0; i<= 3; i++) {
a[i] = (int*)malloc(sizeof(int));
*(a[i]) = i;
printf("*a[%d] = %d\n", i, *(a[i]));
}
The allocated pointer is written to uninitialized memory (you never set a to anything), causing undefined behavior.
So no, it's not at all equivalent to the code in the first example.
You would need something like:
int **a;
a = malloc(3 * sizeof *a);
first, to make sure a holds something valid, then you can use indexing and assign to a[0].
Further, this:
a[i] = (int*)malloc(sizeof(int));
doesn't make any sense. It's assigning to a[i], an object of type int *, but allocating space for sizeof (int).
Finally, don't cast the return value of malloc() in C.
actually malloc it's not that trivial if you really want safe and portable, on linux for example malloc could return a positive response for a given request even if the actual memory it's not even really reserved for your program or the memory it's not writable.
For what I know both of your examples can potentially return a seg-fault or simply crash.
#ruppells-vulture I would argue that malloc is really portable and "safe" for this reasons.
How to allocate dynamic memory for 2d array in function ?
I tried this way:
int main()
{
int m=4,n=3;
int** arr;
allocate_mem(&arr,n,m);
}
void allocate_mem(int*** arr,int n, int m)
{
*arr=(int**)malloc(n*sizeof(int*));
for(int i=0;i<n;i++)
*arr[i]=(int*)malloc(m*sizeof(int));
}
But it doesn't work.
Your code is wrong at *arr[i]=(int*)malloc(m*sizeof(int)); because the precedence of the [] operator is higher than the * deference operator: In the expression *arr[i], first arr[i] is evaluated then * is applied. What you need is the reverse (dereference arr, then apply []).
Use parentheses like this: (*arr)[i] to override operator precedence. Now, your code should look like this:
void allocate_mem(int*** arr, int n, int m)
{
*arr = (int**)malloc(n*sizeof(int*));
for(int i=0; i<n; i++)
(*arr)[i] = (int*)malloc(m*sizeof(int));
}
To understand further what happens in the above code, read this answer.
It is important that you always deallocate dynamically allocated memory explicitly once you are done working with it. To free the memory allocated by the above function, you should do this:
void deallocate_mem(int*** arr, int n){
for (int i = 0; i < n; i++)
free((*arr)[i]);
free(*arr);
}
Additionally, a better way to create a 2D array is to allocate contiguous memory with a single malloc() function call as below:
int* allocate_mem(int*** arr, int n, int m)
{
*arr = (int**)malloc(n * sizeof(int*));
int *arr_data = malloc( n * m * sizeof(int));
for(int i=0; i<n; i++)
(*arr)[i] = arr_data + i * m ;
return arr_data; //free point
}
To deallocate this memory:
void deallocate_mem(int*** arr, int* arr_data){
free(arr_data);
free(*arr);
}
Notice that in the second technique malloc is called only two times, and so in the deallocation code free is called only two times instead of calling it in a loop. So this technique should be better.
Consider this: Just single allocation
int** allocate2D(int m, int n)
{
int **a = (int **)malloc(m * sizeof(int *) + (m * n * sizeof(int)));
int *mem = (int *)(a + m);
for(int i = 0; i < m; i++)
{
a[i] = mem + (i * n);
}
return a;
}
To Free:
free(a);
If your array does not need to be resized (well, you can, but il will be a bit more complicated), there is an easier/more efficient way to build 2D arrays in C.
Take a look at http://c-faq.com/aryptr/dynmuldimary.html.
The second method (for the array called array2) is quite simple, less painful (try to add the tests for mallocs' return value), and way more efficient.
I've just benchmarked it, for a 200x100 array, allocated and deallocated 100000 times:
Method 1 : 1.8s
Method 2 : 47ms
And the data in the array will be more contiguous, which may speed things up (you may get some more efficient techniques to copy, reset... an array allocated this way).
Rather allocating the memory in many different block, one can allocate this in a consecutive block of memory.
Do the following:
int** my2DAllocation(int rows,int columns)
{
int i;
int header= rows *sizeof(int *);
int data=rows*cols*sizeof(int);
int ** rowptr=(int **)malloc(header+data);
if(rowptr==NULL)
{
return NULL:
}
int * buf=(int*)(rowptr+rows);
for(i=0;i<rows;i++)
{
rowptr[i]=buf+i*cols;
}
return rowptr;
}
That is an unnecessarily complicated way of allocating space for an array. Consider this idiom:
int main(void) {
size_t m = 4, n = 3;
int (*array)[m];
array = malloc(n * sizeof *array);
free(array);
}
I have tried the following code for allocating memory to 2 dimensional array.
#include<stdio.h>
#include<malloc.h>
void main(void)
{
int **p;//double pointer holding a 2d array
int i,j;
for(i=0;i<3;i++)
{
p=(int**)(malloc(sizeof(int*)));//memory allocation for double pointer
for(j=(3*i+1);j<(3*i+4);j++)
{
*p = (int*)(malloc(sizeof(int)));//memory allocation for pointer holding integer array
**p = j;
printf(" %d",**p);//print integers in a row
printf("\n");
p++;
}
}
}
Output of the above code is:-
1 2 3
4 5 6
7 8 9
In order to understand 2 dimensional array in terms of pointers, we need to understand how it will be allocated in memory, it should be something like this:-
1 2 3
1000 --> 100 104 108
4 5 6
1004 --> 200 204 208
7 8 9
1008 --> 300 304 308
from the above, we understand that, when we allocate memory to pointer p which is a double pointer, it is pointing to an array of integers, so in this example, we see that the 0x1000 is pointer p.
This pointer is pointing to integer pointer *p which is array of integers, when memory is allocated inside the inner for loop, during first iteration the pointer is 0x100 which is pointing to integer value 1, when we assign **p = j. Similarly it will be pointing to 2 and 3 in the next iterations in the loop.
Before the next iteration of the outer loop, double pointer is incremented, inside the next iteration, as is seen in this example the pointer is now at 0x1004 and is pointing to integer pointer which is an array of integers 4,5,6 and similarly for the next iterations in the loop.
Try the following code:
void allocate_mem(int*** arr,int n, int m)
{
*arr=(int**)malloc(n*sizeof(int*));
for(int i=0;i<n;i++)
*(arr+i)=(int*)malloc(m*sizeof(int));
}
2d Array dynamically array using malloc:
int row = 4;
int column = 4;
int val = 2;
// memory allocation using malloc
int **arrM = (int**)malloc (row*sizeof(int*));
for (int i=0;i<row;i++)
{
arrM[i] = (int*)malloc(column*sizeof(int));
// insert the value for each field
for (int j =0;j<column;j++,val++)
{
arrM[i][j] = val;
}
}
// De-allocation
for (int i=0;i<row;i++)
{
free(arrM[i]);
}
free(arrM);
arrM = 0;
//
// Now using New operator:
//
int **arr = new int*[row];
int k = 1;
for (int i=0;i<row;i++)
{
arr[i] = new int[column];
// insert the value for each field
for (int j =0;j<column;j++,k++)
{
arr[i][j] = k;
}
}
cout<<"array value is = "<<*(*(arr+0)+0)<<endl;
cout<<"array value is = "<<*(*(arr+3)+2)<<endl;
// Need to deallcate memory;
for (int i=0;i<row;i++)
{
delete [] arr[i];
}
delete []arr;
arr = 0;