【问题标题】:multi dimensional char array?多维字符数组?
【发布时间】:2009-10-06 20:05:58
【问题描述】:

我要做的是创建一个二维字符串数组 下面的seg瞬间出错,怎么回事?

void add2(char***b, char *i)
{
    if (!i) {
       b[0][0] = (char*) malloc(120);
       sprintf(b[0][0], "%s", "hithere");
       b[0][1] = (char*) malloc(120);
       sprintf(b[0][1], "%s", "bithere");
    } else {
       strcat(b[0][0], "\\\\");
       strcat(b[0][0], i);
       strcat(b[0][1], "\\\\");
       strcat(b[0][1], i);
    }

}
void add1(char ***b)
{
 add2(b,NULL);
 add2(b,"one");
 add2(b,"two");
 add2(b,"three");
}

int main()
{
 char **keys[2] = {0};
 int i,j;

 add1(keys);

 for (i = 0; keys[i]; i++)
     for (j = 0; keys[j]; j++)
     {
         fprintf(stderr, "%s\n", keys[i][j]);
         free(keys[i][j]);
     }

}

【问题讨论】:

    标签: c multidimensional-array free


    【解决方案1】:

    当您声明数组键时,您是在对编译器说,您希望使用一个包含 2 个指向 chars 指针的指针的数组,并要求它将这些指向 char 指针的指针初始化为 NULL。 一切顺利

    然后你打电话给add1()一切顺利

    然后调用add2() 并尝试将malloc() 的返回值放入b[0] 的第一个元素中。但是b[0] 的值为NULL。 NULL 被放在main() 函数中。 b[0] 没有元素!

    当你有数组数组(数组......) 指针的形式你需要malloc()(和free())每个级别单独.


    编辑

    #include <stdlib.h>
    
    int main()
    {
        char **keys[2] = {0};
        keys[0] = malloc(20 * sizeof *keys[0]); /* 20 strings */
        keys[1] = malloc(20 * sizeof *keys[1]); /* 20 strings */
    
        for (int k=0; k<20; k++) {
            keys[0][k] = malloc(120); /* string with 119 chars + '\0' */
            keys[1][k] = malloc(120); /* string with 119 chars + '\0' */
        }
    
        /* use k[0][0] through k[0][19] */
        /* use k[1][0] through k[1][19] */
    
        for (int k=0; k<20; k++) {
            free(keys[0][k]);
            free(keys[1][k]);
        }
        free(keys[0]);
        free(keys[1]);
    
        return 0;
    }
    

    我把它们都放在了main()函数中,但是如果malloc()s和free()s在它们自己的函数中也是一样的。

    【讨论】:

    • 那么我如何通过 b[n] 分配 b[0]?
    • @pxl:实际上,准确地说,应该是malloc(sizeof(char**) * n);,尽管实际上sizeof(char**)sizeof(char*) 相同。这就是我喜欢将sizeof 与我分配内存的对象一起使用的主要原因:pointer = malloc(n * sizeof *pointer);。我不在乎指针是否指向结构数组或带有数组的结构或其他任何东西; malloc() 总是得到正确的大小:)
    • 嗯,你永远不能太确定...... sizeof(char**) 将是正确的方法。
    【解决方案2】:

    动态分配char * 的二维数组的一般过程是这样的(对于任何其他类型 T,将 char * 替换为所需类型):

    char ***new2DArr(size_t rows, size_t cols)
    {
      char ***newArr = NULL;
      size_t i;
      newArr = malloc(sizeof *newArr * rows);
      if (newArr)
      {
        for (i = 0; i < rows; i++)
        {
          newArr[i] = malloc(sizeof *newArr[i] * cols);
          if (newArr[i])
          {
            /* initialize or assign newArr[i][0] - newArr[i][cols-1] here */
          }
        }
      }
      return newArr;
    }
    

    这假设您提前知道需要多少行和列。请注意,您已经分配了一个指针表;您仍然需要为每个字符串条目分配内存,如下所示:

    char **myArr = new2DArr(10, 10);
    myArr[0][0] = malloc(strlen("Hello, World") + 1);
    if (myArr[0][0])
    {
        strcpy(myArr[0][0], "Hello, World");
    }
    

    如果您想向现有行添加新行或新条目,您将不得不做一些额外的簿记。

    这是一个扩展单行的示例:

    char **extendRow(char **row, char *newEntry, size_t *numEntries)
    {
      char **tmp = realloc(row, *numEntries + 1);
      if (tmp)
      {
        row = tmp;
        row[*numEntries] = malloc(strlen(newEntry) + 1);
        if (row[*numEntries])
        {
          strcpy(row[*numEntries], newEntry);
          (*numEntries)++;
        }
      }
      return row;
    }
    

    你会这样称呼它

    table[i] = extendRow(table[i], "This is a test", &entryCount);
    

    如果指针值被realloc() 更改,结果将被分配回table[i]。我这样做不是为了将指针体操保持在最低限度,而是将指针传递给 table[i]。

    【讨论】:

      猜你喜欢
      • 2017-02-19
      • 1970-01-01
      • 1970-01-01
      • 2016-11-28
      • 2011-08-16
      • 2014-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多