堆上的多维数组 - C.

时间:2016-02-10 09:07:14

标签: c arrays pointers multidimensional-array segmentation-fault

我正在学习C并尝试创建一个可以创建字符串数组的函数。

#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;
}

aoa(数组数组)位于堆上,因此两种方法应该相同。它打印&#34; hi world&#34;在解析函数中,但在main中给出了Segmentation Fault,我的代码有什么问题?

显然我需要释放()所有内容并进行错误检查,但我删除它以显示问题的要点

4 个答案:

答案 0 :(得分:1)

您在parse()中为局部变量保留空间,您需要从array传递指向main的指针,然后在函数内取消引用:

#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;
}

答案 1 :(得分:1)

悲惨的问题在于你的主要问题。您将变量数组作为值发送到解析函数,因此,它不会被解析更改并在MAIN中保持NULL。函数解析的原型应该是

void parse(char ****aoa)

你应该像以下一样把它发送到主要部门:

parse(&array)

但是你的代码过于复杂。尝试在别处启动数组数组,而不是在函数中传递指向它的指针。例如:

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);
}

顺便说一下,请务必确认您的分配没有失败。

答案 2 :(得分:1)

有一个合理的经验法则说,如果你发现自己需要两个以上的间接层,那么你的程序设计就很糟糕了。 (&#34;三星级节目&#34;)

您还使用基于指针的查找表而不是数组。这会导致分段并阻止您将分配的结果视为一块连续的内存。

最重要的是,您的代码还有其他几个问题。 我会考虑从头开始重写它,实际上使用多维数组。这是一个有效的例子:

#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);
    }
  }
}

答案 3 :(得分:0)

您永远不会在函数内取消引用aoa,因此您只需覆盖参数的本地值。函数参数按C中的值传递。您也不需要分配两个字符串数组,这看起来并不正确。