0

我想做的是创建一个二维字符串数组以下段错误立即出现,有什么问题?

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

}
4

2 回答 2

2

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

然后你打电话add1()一切都好

然后你调用并尝试将返回值add2()的第一个元素放入from 。但是 的值为NULL。NULL 被放在函数中。没有元素!b[0]malloc()b[0]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 在它们自己的函数中,它的想法是一样的。

于 2009-10-06T20:16:40.937 回答
1

动态分配 2D 数组的一般过程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);

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

于 2009-10-08T12:42:47.540 回答