Tutorial :Why do I get a segmentation fault (core dumped) when I try to allocate a 4D array?



Question:

I'm trying to allocate a large 4D matrix but I want to do it dynamically. When I just create the static matrix everything works fine so I know I have enough memory for now. However when I try and implement the same thing dynamically it breaks whenever I enter the third dimension and I need to get to a fourth! Can anyone tell me why this code does not work?

#include <iostream>    using namespace std;    static const int time1 = 7;  static const int tlat = 15;  static const int tlon = 17;  static const int outlev = 3;      int main(void)  {      //allocate four dimensional dataIn      int ****dataIn;      dataIn = new int ***[time1];      if (dataIn == NULL) { return 1; }        for(int i = 0 ; i < time1 ; i++) {           dataIn[i] = new int **[tlat];          if (dataIn[i] == NULL) { return 1; }            for(int j = 0 ; j < tlat ; j++) {              dataIn[i][j] = new int *[tlon];              if (dataIn[i][j] == NULL) { return 1; }                for(int k = 0 ; k < tlon ; k++) {                  dataIn[i][j][k] = new int[outlev];                  if (dataIn[i][j][k] == NULL) { return 1; }              }          }      }      //there is more code that happens here to add values to dataIn      //and eventually output it but I know all of that works              return 0;  }  

I have tried many different variations on this code, and even used malloc instead of new, but I cannot get it working. Any help will be greatly appreciated.


Solution:1

Have you run this in a debugger? To my eyes the code looks fine, but a debugger will tell you where it's crashing which alone may be enough to help you fix it


Solution:2

You're probably best off allocating all the memory in a flat array and then calculating the indices yourself. Wrapping the whole thing in an object for encapsulation.

class Matrix {  private:          int* data;                  int[] sizes;          int nDimensions;    public:          // allocates the data pointer and copies the other parameters          Matrix(int[] sizes, int nDimensions);             // frees the data and sizes arrays          ~Matrix();            // calculates the cell position and returns it          int getCell(int[] coordinates);            // calcultes the cell position and sets its value          void setCell(int[] coordinates, int value);    private:          // used by getCell and setCell, calculates the cell's           // location in the data array          size_t calculateCellPosition(int[] coordinates);  };  


Solution:3

It compiles and runs fine on my Linux machine.

BTW, with standard C++, new would throw a std::bad_alloc exception (instead of returning NULL) when it's unable to allocate the memory. So it might be worth catching that exception instead of testing for a NULL pointer.


Solution:4

As pointed out by cmeerw, testing against NULL or 0 is not needed in std-c++.

It would help if you could add a comment to the exact spot where you get a segv.

Also: Which compiler are you using and on which OS?


Solution:5

Check out boost::multiarray, it does exactly what you want, except more efficiently by only doing a single heap allocation.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »