【问题标题】:Dynamic memory allocation for char***char的动态内存分配***
【发布时间】:2017-08-27 16:58:28
【问题描述】:

我试图为 char*** 动态分配内存。

char*** tas;

使用 char*** 我想描述一个只有 2 列的字符串表。

我试图解决的主要问题不是编译程序,而是让它在没有分段错误的情况下运行。

我认为问题在于未正确使用 realloc。 检查 realloc/calloc/malloc 的手册页

void *realloc(void *ptr, size_t size);
void *malloc(size_t size);
void *calloc(size_t nmemb, size_t size);

我发现我必须生成正确的 size_t 变量来发送分配函数。

这方面的关键代码行如下:

tas         = (char ***)realloc(tas,sizeof(char **)*(i+1));
tas[i]      = (char **)calloc(2,sizeof(char *));
tas[i][0]   = (char *)calloc(lenKey+1,sizeof(char));
tas[i][1]   = (char *)calloc(lenValue+1,sizeof(char));
++i;

tas 是字符***。

--------编辑-------

我逐个编译了一个答案,并将我找到的解决方案发布在这里。

【问题讨论】:

  • 如果你发现自己在写***,那你就做错了。
  • @user2357112 以上是为了研究目的,学习东西没有错……我知道结构是一样的,但我想了解更多的分配函数。
  • 做一个三星级的C程序员不是一个顺从者!如果您需要一个多维数组,请使用一个。
  • 有时可能有理由使用不规则的二维数组,即char** 而不是char string_table[ROWS][COLUMNS]char *string_table[],但实际上从来没有一个可以使用@987654329 @。如果目标是在稀疏数组上节省内存,请使用压缩的稀疏数组格式。

标签: c dynamic-memory-allocation realloc calloc


【解决方案1】:

您的初始分配应使用malloccalloc 而不是realloc;否则,您的初始指针参数必须是 NULL:

char ***tas = malloc( (i+1) * sizeof *tas );

char ***tas = calloc( i+1, sizeof *tas );

char ***tas = realloc( NULL, (i+1) * sizeof *tas );

char ***tas = NULL;
tas = realloc( tas, (i+1) * sizeof *tas );

否则你已经很接近了——只是失去无关的演员表。

tas[i] = calloc( 2 * sizeof *tas[i] );

tas[i][0] = calloc( lenKey + 1, sizeof *tas[i][0] );
tas[i][1] = calloc( lenValue + 1, sizeof *tas[i][1] );

与往常一样,检查每个*alloc 调用的结果。

【讨论】:

    【解决方案2】:

    这并不难,你只需要保持头脑清醒。

    首先,请记住一般模式:要分配 n 类型为 T 的元素的数组,请使用:

    T * p = malloc(n * sizeof(T));
    

    然后在[0, n) 范围内为i 初始化值p[i],然后在完成后取消初始化元素(如有必要),然后释放数组分配:

    free(p);
    

    现在只需为您的字符串数组递归地执行此操作,记住字符串是字符数组,mn 字符串列:

    // allocate the table (the row pointers)
    char *** tas = malloc(m * sizeof(char**));
    
    for (size_t i = 0; i != m; ++i)
    {
        // allocate each row (the row cells)
        tas[i] = malloc(n * sizeof(char*));
        for (size_t j = 0; j != n; ++j)
        {
            // initialize the row cell by allocating the string
            tas[i][j] = /* allocate string */
        }
    }
    

    在回来的路上,释放一切:

    for (size_t i = 0; i != m; ++i)
    {
        for (size_t j = 0; j != n; ++j)
        {
            free(tas[i][j]);  // free the string
        }
    
        free(tas[i]);         // free the row
    }
    
    free(tas);                // free the table
    

    【讨论】:

      【解决方案3】:

      char*** 就像一个字符串表。

            R\C  ||---1-----|----2----|   
         |---1---||string11 |string12 |
         |---2---||string21 |string22 |
         |---3---||string31 |string32 |
         | ....  ||  .....     ...... |
         |-(N-1)-||str N-1.1|str N-1.2|
         |---N---||stringN1 |stringN2 |
      

      这是一个带有 cmets 的演示源代码,以便了解如何实现类似的功能:

      #include <unistd.h>
      #include <stdio.h>
      #include <string.h>
      #include <ctype.h>
      #include <stdlib.h>
      void rellocateFunction(size_t lenKey, size_t lenValue);
      void firstAllocateFunction(size_t lenKey, size_t lenValue);
      int i=0;
      char*** tas;
      
      int main(){
          int j=0;
          size_t length1, length2; 
          char* stringN1=(char *)malloc(10*sizeof(char));
          char* stringN2=(char *)malloc(10*sizeof(char));
          while(1){
              printf("dragons\n");
              printf("MAIN: Enter string[%d][0]:",j); scanf("%s", stringN1);
              printf("MAIN: Enter string[%d][1]:",j); scanf("%s", stringN2);
              length1 = strlen(stringN1); // You need the length of the string to pass it as an argumnet to allocation functions
              length2 = strlen(stringN2); // Same as above comment
              if(j==0) firstAllocateFunction(length1,length2); // We cant start with the use of realloc. So here you are initiliazing the allocation with calloc only.
              else rellocateFunction(length1,length2); // When we already have entries in the table, we are going to use this function to allocate more memory for the new entries.
              strcpy(tas[j][0],stringN1);  // Population of char*** at row j and col 0
              strcpy(tas[j][1],stringN2);  // Population of char*** at row j and col 1
              j++;
              for (int c=0; c<j; c++) // Print the results
              {
                  printf("tas[%d][0]:<%s>\n",c, tas[c][0]);
                  printf("tas[%d][1]:<%s>\n",c, tas[c][1]);
              }
          } // Notice the forever ongoing loop... That's to test if the code works. Cancel the execution with ctrl+c
          return 0;
      }
      
      void firstAllocateFunction(size_t len1, size_t len2){ 
      tas         = (char ***)calloc(1,sizeof(char **)); //One char*** pointer
      tas[i]      = (char **)calloc(2,sizeof(char *));   //pointin to 2 char** 
      tas[i][0]   = (char *)calloc(len1+1,sizeof(char)); //containing len1+1 
      tas[i][1]   = (char *)calloc(len2+1,sizeof(char)); //and len2+1 elements of sizeof(char) bytes.
      ++i;
      }
      
      void rellocateFunction(size_t len1, size_t len2){
      tas         = (char ***)realloc(tas,sizeof(char **)*(i+1)); //One more char***
      tas[i]      = (char **)calloc(2,sizeof(char *));   ////////////////////
      tas[i][0]   = (char *)calloc(len1+1,sizeof(char)); // Same as above //
      tas[i][1]   = (char *)calloc(len2+1,sizeof(char)); ///////////////////
      ++i;
      }
      

      我使用了 calloc,因为我想避免使用 memset 来初始化字符串。其余的用 cmets 解释。

      请注意,您必须在第一次使用不同的 function() 时为 char*** 分配内存,而不是在其余时间基本上重新分配 char*** 的内存。

      警告。上面的代码没有实现 free() 函数(强烈推荐这样做。所以要小心不要让死数据填满你的内存。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-28
        • 2011-06-08
        相关资源
        最近更新 更多