Brayan lemus Brayan lemus - 1 month ago 11
C Question

<error: Cannot access memory at address 0x0> 3d array malloc

I have a program that requires 3D arrays in order to do the Job.

This is the way I'm declaring the arrays:

double ***Xab,**Rab, ***Vab;


This is the way I'm making the arrays:
Context: N = 4 , coordenadas = 3


Xab = malloc( N * sizeof(double));
Vab = malloc( N * sizeof(double));
Rab = malloc( N * sizeof(double));
for ( z = 0; z < N ; z++) {
Xab[z] = (double **)malloc( N * sizeof(double));
Vab[z] = (double **)malloc( N * sizeof(double));
Rab[z] = (double *)malloc(N * sizeof(double));
for ( v = 0; v < coordenadas; v++) {
Xab[z][v] = (double *)malloc( coordenadas * sizeof(double));
Vab[z][v] = (double *)malloc( coordenadas * sizeof(double));
}
}


This is the way I fill the arrays:

for ( z = 0; z < N; z++) {
for ( v = 0; v < N; v++) {
for ( w = 0; w < coordenadas; w++) {
Xab[z][v][w] = y[z][w] - y[v][w];
Vab[z][v][w] = y[z][w+3] - y[v][w+3];
}
Rab[z][v] = sqrt( pow(Xab[z][v][0],2)+ pow(Xab[z][v][1],2)
+ pow(Xab[z][v][2],2) );
}
}


The problem is directly with
Xab
and
Vab
( the 3D arrays ), everything works fine as long as N < 4, but when N > 3 I get a Segmentation fault.

I Tried to debug it ( gdb ) on OpenSuse Leap 42.1 ( x86_64 ).

Program received signal SIGSEGV, Segmentation fault.
0x0000000000405009 in PostNewtonNcuerposV2 (x=0, y=0x60a040, dvdt=0x60a4e0, M=0x60a010, N=4)
at NbodyPNV2.c:34

34 Xab[z][v][w] = y[z][w] - y[v][w];




1: y[z][w] = 0

2: y[v][w] = 59165672784.100632

3: w = 0

4: v = 3

5: z = 0

6: Xab[z][v][w] = "error: Cannot access memory at address 0x0"

So I tried the following:

(gdb) display Vab[3][3][3]

7: Vab[3][3][3] = error: Cannot access memory at address 0x18

(gdb) display Vab[3][2][3]

9: Vab[3][2][3] = 6.4687520944348569e-319




So, that's the problem. the 2D arrays memory allocation works fine above N > 3 but the 2D segment of the 3D arrays doesn't, and is for all 3D arrays that i have.

I think that it might be because of the way making the arrays. While investigating i encounter a post talking about a stack overflow ( ironically ) en the OS itself, but i couldn't find any kind of solution. Every other post that i could find solves it with a correct control variable usage ( z,v,w in my case ) or with a better declaration of the arrays. In this cases the code didn't work at all, but mine does (as expected ) with N < 3.

So, the main question is the following.
Is there any thing wrong with the allocation of the 3d arrays? or
Is there any way the let the program access or change the memory address that is trying to use?

Any idea is appreciated.

Thank you in advance.

Answer

You're not allocating the proper amount of memory for the array.

First, the allocations for the first dimension should be a multiple of sizeof(double **), since that's the type you're creating an array for. Similarly, the allocations for the second dimension should be a multiple of sizeof(double *).

Secondly, the range of the inner loop is not correct. Since the second dimension has N elements, you want that loop to run N times, not coordenadas times. So when N is larger than coordenadas, you don't have enough space for the elements of the second dimension.

Also, don't cast the return value of malloc, as that can lead to subtle bugs.

With the above fixes, you should now have this:

Xab = malloc( N * sizeof(double **));
Vab = malloc( N * sizeof(double **));
Rab = malloc( N * sizeof(double *));
for ( z = 0; z < N ; z++) {
  Xab[z] = malloc( N * sizeof(double *));
  Vab[z] = malloc( N * sizeof(double *));
  Rab[z] = malloc(N * sizeof(double));
  for ( v = 0; v < N; v++) {
    Xab[z][v] = malloc( coordenadas * sizeof(double));
    Vab[z][v] = malloc( coordenadas * sizeof(double));
  }
}