Multidimensional array on the heap - C

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-07 00:26:32

You reserve space for a local variable in parse(), you need to pass a pointer to array from main and then dereference inside the function:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void parse(char ****aoa)
{
    char *string = calloc(9, sizeof(char));        //create a string of size 8+1
    strcpy(string, "hi world");                   // put text in that array
    char **array = calloc(10, sizeof(char *));    //create an array of strings
    *aoa = calloc(10, sizeof(char *));             //create and array of arrays
    *(aoa[0]) = array;                               //assign string array to the 0th elements of new array
    array[0] = string;                            //assign our string to 0th element of string carry
    printf("%s\n", *(aoa[0][0]));                    //print 0th element of 0th array. 
}


int main()
{
    char ***array = NULL;
    parse(&array);
    printf("%s\n", array[0][0]);
    return 1;
}

The problem tragically lies in your main. You send your variable array to the parse function as a value, hence, it is not changed by parse and stays NULL in the MAIN. The prototype of your function parse should be

void parse(char ****aoa)

and you should send it to the main like this :

parse(&array)

But you are overcomplicating the code. Try to initiate your array of arrays elsewhere instead of passing a pointer to it in the function. for example :

char ***getArray(void)
{
char ***ret;                                   //the array you return
char *string = calloc(9, sizeof(char));        //create a string of size 8+1
strcpy(string, "hi world");                   // put text in that array
char **array = calloc(10, sizeof(char **));    //create an array of strings
ret = calloc(10, sizeof(char ***));             //create and array of arrays
ret[0] = array;                               //assign string array to the 0th elements of new array
array[0] = string;                            //assign our string to 0th element of string carry
return (ret);
}


int main()
{
char ***array = getArray();
printf("%s\n", array[0][0]);
return (0);
}

And by the way, always verify that your allocations did not fail.

There is a sound rule of thumb saying that if you ever find yourself in need of more than two levels of indirection, then your program design is bad. ("Three star programming")

You are also using pointer-based lookup-tables rather than arrays. This causes segmentation and prevents you to regard the allocated result as a chunk of contiguous memory.

On top of that, your code has several other issues. I would consider rewriting it from scratch and actually use multi-dimensional arrays instead. Here is a working example:

#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>

bool create_string_array2d (size_t x, 
                            size_t y, 
                            size_t max_length, 
                            char (**string_array)[x][y][max_length]);

void print_string_array2d (size_t x,
                           size_t y,
                           size_t max_length,
                           char string_array[x][y][max_length]);

static void fill_with_junk (size_t x,
                            size_t y,
                            size_t max_length,
                            char string_array[x][y][max_length]);

int main()
{
  const size_t X = 9;
  const size_t Y = 10;
  const size_t MAX_CHARS = sizeof("hi world xx yy");

  char (*array)[X][Y][MAX_CHARS];
  bool result;

  result = create_string_array2d(X, Y, MAX_CHARS, &array);

  if(result == false)
  {
    printf("out of memory, halt & catch fire");
    return 0;
  }

  fill_with_junk(X, Y, MAX_CHARS, *array);

  print_string_array2d(X, Y, MAX_CHARS, *array);

  free(array);

  return 0;
}


bool create_string_array2d (size_t x, 
                            size_t y, 
                            size_t max_length, 
                            char (**string_array)[x][y][max_length])
{
  *string_array = calloc(1, sizeof(char[x][y][max_length]));

  return string_array != NULL;
}

void print_string_array2d (size_t x,
                           size_t y,
                           size_t max_length,
                           char string_array[x][y][max_length])
{
  for(size_t i=0; i<x; i++)
  {
    for(size_t j=0; j<y; j++)
    {
      printf("%s\n", string_array[i][j] );
    }
    printf("\n");
  }
}

static void fill_with_junk (size_t x,
                            size_t y,
                            size_t max_length,
                            char string_array [x][y][max_length])
{
  for(size_t i=0; i<x; i++)
  {
    for(size_t j=0; j<y; j++)
    {
      char junk [sizeof("hi world xx yy ")] = "hi world ";
      char num  [sizeof("xx ")];
      sprintf(num, "%.2d ", (int)i);
      strcat(junk, num);
      sprintf(num, "%.2d", (int)j);
      strcat(junk, num);

      strcpy(string_array[i][j], junk);
    }
  }
}

You never dereference aoa inside the function, so you just overwrite the argument's local value. Function arguments are passed by value in C. You also shouldn't need to alllocate two string arrays, that doesn't seem right.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!