-2

I have a 3D array as such char **arr[1];

I have it dynamically allocated like that:

*arr = calloc(10, sizeof(char*)); // Will be using 0-9
for(i = 0; i < 10; i ++)
    *arr[i] = malloc(3); // will be using 0-2

It crashes. Even though, I can't provide you with the entire library, in which I read/write to that array, but the answer of the question is the allocation correct, will help me debug and throw out the possibility of wrong or impossible allocation.

Protogrammer
  • 225
  • 1
  • 3
  • 8
  • 3
    `arr` looks like a perfectly *one*-dimensional array to me. If you want 9x3 characters, maybe you want `char arr[9][3]`? – Kerrek SB Dec 05 '14 at 10:12
  • one dimensional array of two dimensional array of pointers? Besides the point.. can't I threat it like it is intended. No, I actually want one char additional item for each of the elements. – Protogrammer Dec 05 '14 at 10:12
  • 3
    No, just a one-dimensional array (of pointers). Arrays aren't the same as pointers. – Kerrek SB Dec 05 '14 at 10:13
  • Well okay, thats the question, how do I do it correct. Because I treid with a proper allocation for `char ***arr` but resulted in weird leaks. – Protogrammer Dec 05 '14 at 10:14
  • How the hell is that question duplicate ?? The question you provided as the given answer is for multidimensional arrays but not 3D arrays in general. The answer approved there is for allocating 2D array. – Protogrammer Dec 05 '14 at 10:34
  • 1
    Simply add one more [] and there you go. The rules for 2D arrays apply recursively to 3D, 4D, 5D and so on as well. The main issue here is that you are confusing a pointer-to-pointer based lookup table for a multi-dimensional array, which seems to be a common misunderstanding. – Lundin Dec 05 '14 at 10:43
  • The 3D allocation method is slightly different. Yes I confused them. It seems I have to post another question now of how to obtain `arr[0]` as `char*` not `char**` because thats the problem I ran into, using `char***` instead, before I posted this question. – Protogrammer Dec 05 '14 at 10:44
  • Or you could read the answers in the linked duplicate. You don't want `char*` nor `char**`, you want an array pointer which is `char(*)[]` where the number of [] is variable. – Lundin Dec 05 '14 at 10:46
  • (You _could_ use `char*` for a "mangled" multi-dimensional array as mentioned in one answer to the linked duplicate, but those are rather burdensome and ugly, so I wouldn't recommend them.) – Lundin Dec 05 '14 at 10:50
  • I used the second method of mch, which was what the question originally consisted of. It works, but leaves traces of leaks.. If I try to null-terminate it.. the program crashes. – Protogrammer Dec 05 '14 at 10:55
  • It works without leaks if I null-terminate arr[0][1][3]. – Protogrammer Dec 05 '14 at 11:02
  • don't forget to free the memory afterwards, see the edit in my answer. – mch Dec 05 '14 at 11:26
  • @mch thanks. It throw u/b if I don't say: `arr[0][i][9] = '\0';` where i is each item 0-9. And so much crashes when I try to fill out arr[0]s ;x – Protogrammer Dec 05 '14 at 11:34

1 Answers1

0

I would do it like this:

char** arr;
arr = malloc(10 * sizeof *arr);
if (!arr)
  return -1;
for (int i = 0; i < 10; i++)
{
  arr[i] = malloc(3);
  if (!arr[i])
    return -1;
}

if you really need this 3d array, the correct way should be:

char** arr[1];
arr[0] = malloc(10 * sizeof **arr);
if (!arr[0])
  return -1;
for (int i = 0; i < 10; i++)
{
  arr[0][i] = malloc(3);
  if (!arr[0][i])
    return -1;
}

when you are done you should free the memory like this (this works for the second example):

for (int i = 0; i < 10; i++)
  free(arr[0][i]);
free(arr[0]);

other methods are: char arr[3][10]; or char arr[1][3][10];, but an array with only 1 value doesn't make much sense.

mch
  • 9,424
  • 2
  • 28
  • 42