【问题标题】:Multidimensional array on the heap - C堆上的多维数组 - C
【发布时间】:2016-05-20 13:04:38
【问题描述】:

我正在学习 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(数组的数组)在堆上,所以这两种方法应该是一样的。它确实在解析函数中打印“hi world”,但在 main 中给出了 Segmentation Fault,我的代码有什么问题?

显然我需要 free() 一切并进行错误检查,但我删除了它以显示问题的要点

【问题讨论】:

  • 是什么阻止您为 10x10 数组分配 100 并将其用作 10x10 数组?
  • 我稍后会为选定的字符串数组动态重定位空间。
  • 3x3 示例:最初看起来像这样:{{hi, my, name}, {one, two, three}, {red, green, blue}}。但稍后我可能需要将其更改为:{{hi, my, name, is, Alex}, {one, two}, {cyan, magenta, yellow, key}}
  • char **array 不是多维数组,this =>> char array[SIZE][SIZE] 是多维数组。

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


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      可悲的是,问题在于您的主要问题。您将变量数组作为值发送到 parse 函数,因此,它不会被 parse 更改并在 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);
      }
      

      顺便说一句,请始终确认您的分配没有失败。

      【讨论】:

        【解决方案4】:

        有一个合理的经验法则说,如果您发现自己需要两个以上的间接级别,那么您的程序设计就是糟糕的。 (《三星级编程》)

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

        除此之外,您的代码还有其他几个问题。 我会考虑从头开始重写它并实际使用多维数组。这是一个工作示例:

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

        【讨论】:

          猜你喜欢
          • 2010-09-25
          • 1970-01-01
          • 2019-01-05
          • 1970-01-01
          • 2023-04-04
          • 2012-03-11
          • 1970-01-01
          • 1970-01-01
          • 2015-12-08
          相关资源
          最近更新 更多