0

I have this 3D matrix I allocated as one block of memory, but when I try to write to the darn thing, it gives me a segmentation fault. The thing works fine for two dimensions, but for some reason, I'm having trouble with the third...I have no idea where the error is in the allocation. It looks perfect to me.

Here's the code:

phi = new double**[xlength];
phi[0] = new double*[xlength*ylength];
phi[0][0] = new double[xlength*ylength*tlength];
for (int i=0;i<xlength;i++)
{
    phi[i] = phi[0] + ylength*i;
    for (int j=0;j<ylength;j++)
    {
        phi[i][j] = phi[i][0] + tlength*j;
    }
}

Any help would be greatly appreciated. (Yes, I want a 3D matrix)

Also, this is where I get the segmentation fault if it matters:

for (int i = 0; i < xlength; i++)
    {
        for (int j = 0; j < ylength; j++)
        {
            phi[i][j][1] = 0.1*(4.0*i*h-i*i*h*h)
            *(2.0*j*h-j*j*h*h);
        }
    }

This does work for two dimensions though!

phi = new double*[xlength];
phi[0] = new double[xlength*ylength];
for (int i=0;i<xlength;i++)
{
    phi[i] = phi[0] + ylength*i;
}
Mechy
  • 259
  • 1
  • 4
  • 14
  • See: http://stackoverflow.com/a/2216055/179910 – Jerry Coffin May 15 '13 at 04:49
  • pls use `c++ containers` – Bill May 15 '13 at 04:49
  • the second code works *incorrectly*, it is [undefined behavior](http://en.wikipedia.org/wiki/Undefined_behavior), just some memory leak which don't crash yet (but could crash later). Use a memory leakage detector like [valgrind](http://valgrind.org) – Basile Starynkevitch May 15 '13 at 05:12
  • Yeah, it didn't work after all. The implementation just doesn't seem to work for 3 dimensions. – Mechy May 15 '13 at 05:56
  • The fact that a program does not crash don't mean that it works; and undefined behavior could even manifest as apparently working sometimes (but would crash with other systems, scenarii, etc..) – Basile Starynkevitch May 15 '13 at 05:57
  • Works here too http://stackoverflow.com/questions/16555862/how-do-i-allocate-one-block-of-memory-with-new – Mechy May 15 '13 at 06:01
  • Just out of curiosity: what are your application for 3d matrices? Have you considerd to use a library for tensors (like http://code.google.com/p/ltensor/)? – ChaosCakeCoder May 15 '13 at 06:09
  • I use it for computing large chunks of data, but for increased efficiency, I wanted to allocate it all as one contiguous chunk. The code I posted above works for 2D (I edited it when I saw an error), but it won't work for a 3rd dimension. – Mechy May 15 '13 at 07:16
  • Maybe it would be more usefull/efficient to derive a formular that directly gives you the memory position of the entry (i,j,k). For 2d it is i+j*n where n is the number of rows (if i remember the formular correctly). This enables the compiler also the use loop-unrolling. – ChaosCakeCoder May 15 '13 at 07:29

1 Answers1

0

You did not allocate other submatrixes like e.g. phi[1] or phi[0][1]

You need at least

phi = new double**[xlength];
for (int i=0; i<xlength; i++) { 
    phi[i] = new double* [ylength];
    for (int j=0; j<ylength; j++) { 
       phi[i][j] = new double [zlength];
       for (k=0; k<zlength; k++) phi[i][j][k] = 0.0;
    }
}

and you should consider using std::vector (or even, if in C++2011, std::array), i.e.

std::vector<std::vector<double> > phi;

and then with std::vector you'll need to phi.resize(xlength) and a loop to resize each subelement phi[i].resize(ylength) etc.


If you want to allocate all the memory at once, you could have

double* phi = new double[xlength*ylength*zlength]

but then you cannot use the phi[i][j][k] notation, so you should

#define inphi(I,J,K) phi[(I)*xlength*ylength+(J)*xlength+(K)]

and write inphi(i,j,k) instead of phi[i][j][k]


Your second code does not work: it is undefined behavior (it don't crash because you are lucky, it could crash on other systems....), just some memory leak which don't crash yet (but could crash later, perhaps even by re-running the program again). Use a memory leakage detector like valgrind

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547