My code is to allocate and initialize the array as follows (floatalloc2
is a function used to allocate the 2D array):
#include <stdio.h>
#include <stdlib.h>
void alloc_arr(int adjwfd, int nx, int nz, float **G, float **L1, float **L2)
{
G = floatalloc2(nx, nz);
switch (adjwfd){
case 1:
L1 = floatalloc2(nx, nz);
break;
case 2:
L2 = floatalloc2(nx, nz);
break;
}
}
void init_arr(int adjwfd, int nx, int nz, float **G, float **L1, float **L2)
{
memset(G[0],0,nx*nz*sizeof(float));
switch (adjwfd){
case 1:
memset(L1[0],0,nx*nz*sizeof(float));
break;
case 2:
memset(L2[0],0,nx*nz*sizeof(float));
break;
}
}
int main(int argc, char *argv[])
{
int adjwfd_P=1, nx=10, nz=10;
float **glob=NULL, **local1=NULL, **local2=NULL;
alloc_arr(adjwfd_P, nx, nz, glob, local1, local2);
init_arr(adjwfd_P, nx, nz, glob, local1, local2);
exit(0);
}
It passes the compilation. But when I run this code, it goes wrong says:
YOUR APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault (signal 11)
However, I found that if I change the alloc_arr
as follows, it runs successfully:
#include <stdio.h>
#include <stdlib.h>
void alloc_arr(int adjwfd, int nx, int nz, float ***G, float ***L1, float ***L2)
{
*G = floatalloc2(nx, nz);
switch (adjwfd){
case 1:
*L1 = floatalloc2(nx, nz);
break;
case 2:
*L2 = floatalloc2(nx, nz);
break;
}
}
void init_arr(int adjwfd, int nx, int nz, float **G, float **L1, float **L2)
{
memset(G[0],0,nx*nz*sizeof(float));
switch (adjwfd){
case 1:
memset(L1[0],0,nx*nz*sizeof(float));
break;
case 2:
memset(L2[0],0,nx*nz*sizeof(float));
break;
}
}
int main(int argc, char *argv[])
{
int adjwfd_P=1, nx=10, nz=10;
float **glob=NULL, **local1=NULL, **local2=NULL;
alloc_arr(adjwfd_P, nx, nz, &glob, &local1, &local2);
init_arr(adjwfd_P, nx, nz, glob, local1, local2);
exit(0);
}
My question is why I have to take the address of the 2D array, and in the alloc_arr
define 3D array only for the allocation part, whereas in other functions such as init_arr
, I can just pass the original 2D array into the function?
why I have to take the address of the 2D array, and in the alloc_arr define 3D array only for the allocation part,......
In this case:
alloc_arr(adjwfd_P, nx, nz, glob, local1, local2);
You are actually passing the last three argument as NULL
to alloc_arr()
function parameter G
, L1
and L2
as the glob
, local1
and local2
are initialized with NULL
and in alloc_arr()
void alloc_arr(int adjwfd, int nx, int nz, float **G, float **L1, float **L2)
{
G = floatalloc2(nx, nz);
.....
L1 = floatalloc2(nx, nz);
.....
L2 = floatalloc2(nx, nz);
.....
the memory is getting allocated to G
, L1
and L2
which are local variables of alloc_arr()
function. In the main()
, the glob
, local1
and local2
are still null pointers after alloc_arr()
function returned. These null pointers passed to init_arr()
and when trying to access them in init_arr()
your program is giving segmentation fault.
and in this case
alloc_arr(adjwfd_P, nx, nz, &glob, &local1, &local2);
you are passing the address of pointers glob
, local1
and local2
as argument to alloc_arr()
function parameters G
, L1
and L2
, which means G
, L1
and L2
will hold address of glob
, local1
and local2
pointers respectively.
void alloc_arr(int adjwfd, int nx, int nz, float ***G, float ***L1, float ***L2)
{
*G = floatalloc2(nx, nz);
.....
*L1 = floatalloc2(nx, nz);
.....
*L2 = floatalloc2(nx, nz);
.....
Dereferencing the pointer G
will give glob
pointer i.e. *G
is glob
. Similarly, dereferencing *L1
and *L2
will give pointer local1
and local2
respectively. So, when allocating memory to *G
, *L1
and *L2
will actually allocate memory to glob
, local1
and local2
pointers.
whereas in other functions such as init_arr, I can just pass the original 2D array into the function?
Look at this:
alloc_arr(adjwfd_P, nx, nz, &glob, &local1, &local2);
init_arr(adjwfd_P, nx, nz, glob, local1, local2);
the alloc_arr()
will allocate memory to glob
, local1
and local2
which means after returning from alloc_arr()
(assuming everything works as expected) the pointers glob
, local1
and local2
are pointing to valid memory locations. In the init_arr()
you are just passing those memory locations as argument to the init_arr()
function parameters G
, L1
and L2
. In the init_arr()
, accessing G
, L1
and L2
means it is accessing those memory locations.
Additional:
Follow good programming practice, make sure to free the allocated memory before program exits.