3

I am trying to allocate memory for a triple pointer. I have the following:

int i, j;
int n = 4;

int ***X = (int ***) malloc(sizeof(int) * n);
for(i = 0; i < n; i++){
      printf("h\n");
      X[i] = (int **) malloc(sizeof(int) * n);
      for(j = 0; j < n; j++){
            printf("j\n");
            X[i][j] = (int *) malloc(sizeof(int) * n);
      }
}

X[0][0][0] = 14;
X[1][2][2] = 15;

When I run this on Linux, I get *** glibc detected *** triplePointer: double free or corruption (out): 0x0000000000ea3050 *** error which I have completely no idea what it is implying. But when I run it on Windows with the -Wall flag, I get no errors. Can someone perhaps help me to find where my error is at.

Also, I am currently hard coding by having the statement X[0][0][0] = 14;. Is there a way that I can populate all the slots of this triple pointer by some random values?

user3754974
  • 279
  • 1
  • 6
  • 15
  • 4
    Each of your `sizeof()` arguments is incorrect except the most inner. And I suspect when run under windows you're compiling as 32-bit, which has identical sizes for `int` and arbitrary data pointers. Compile it as a 64-bit process and you'll potentially see similar behavior as your Linux distro. – WhozCraig Jul 30 '14 at 05:33
  • Of course! I can't believe I missed that. Ahh.... – user3754974 Jul 30 '14 at 05:35
  • @user3754974 [This will clear your all doubts](http://c-faq.com/aryptr/dynmuldimary.html) – Jayesh Bhoi Jul 30 '14 at 05:50

1 Answers1

10

Try the following code-

int ***X = (int ***) malloc(sizeof(int**) * n); //FIX 1
for(i = 0; i < n; i++){
  printf("h\n");
  X[i] = (int **) malloc(sizeof(int*) * n);  // FIX 2
  for(j = 0; j < n; j++){
        printf("j\n");
        X[i][j] = (int *) malloc(sizeof(int) * n);
  }
}

When you are allocating memory for Triple pointer first you need to allocate memory n double pointers.

int ***X = (int ***) malloc(sizeof(int**) * n); // Not sizeof(int)

Then for that double pointer you need to allocate memory for n single pointers

for(i = 0; i < n; i++)
  X[i] = (int **) malloc(sizeof(int*) * n);

For that single pointers you need to allocate memory finally

for(i = 0; i < n; i++)
 for(j = 0; j < n; j++)
        X[i][j] = (int *) malloc(sizeof(int) * n);

This is the way of allocation!


Though a bit more work, it is arguably more straight-forward to use the size of the target pointer dereferenced than coding the type in the sizeof() operator. See below, including the advised removal of malloc() casts in C programs.

int ***X = malloc(sizeof(*X) * n);
for (i = 0; i < n; i++)
{
    printf("h\n");
    X[i] = malloc(sizeof(*(X[i])) * n);
    for (j = 0; j < n; j++)
    {
        printf("j\n");
        X[i][j] = malloc(sizeof(*(X[i][j])) * n);
    }
}

Note the only place you see an actual type in this is int ***X. Everything else is based on that initial declaration. Why is this arguably "better"? Ex: To change this entire thing to a 3D matrix of double would require changing one line: double ***X = ...

Community
  • 1
  • 1
Sathish
  • 3,740
  • 1
  • 17
  • 28