如何为C中未知长度的字符串数组分配内存

时间:2012-11-12 20:25:41

标签: c arrays string dynamic realloc

我有一个数组,比方说,文本,包含由另一个函数读入的字符串。弦的长度是未知的,它们的数量也是未知的。 我应该如何尝试将内存分配给字符串数组(而不是字符串本身,它们已作为单独的数组存在)?

我现在设置的内容似乎很好地读取了字符串,并且似乎正在进行我想要正确完成的后处理(我尝试使用静态数组)。但是,当我尝试printf文本元素时,我遇到了分段错误。更确切地说,当我尝试打印文本的特定元素(例如文本[3]或文本[5])时,我会出现分段错误。我认为这意味着我正在错误地为文本分配内存并且所有读取的字符串都没有正确保存到文本中?

到目前为止,我尝试了不同的方法,例如首先分配一定数量的size_t=k , k*sizeof(char),然后重新分配更多内存(使用realloc k*sizeof(char)) if cnt == (k-2),其中cnt是**文本的索引。

我试图搜索这个,但我发现的唯一类似的问题是设定数量的未知长度的字符串。

我想尽可能多地弄清楚,并且由于这个原因没有发布实际的代码。但是,如果没有任何意义,我会发布它。

编辑:这是代码

int main(void){
  char **text;
  size_t k=100;
  size_t cnt=1;
  int ch;
  size_t lng;

  text=malloc(k*sizeof(char));

  printf("Input:\n");

  while(1) {

    ch = getchar();
    if (ch == EOF) {
      text[cnt++]='\0';
        break;
    }

    if (cnt == k - 2) {
      k *= 2;
      text = realloc(text, (k * sizeof(char))); /* I guess at least this is incorrect?*/
    }

    text[cnt]=readInput(ch); /* read(ch) just reads the line*/
    lng=strlen(text[cnt]);
    printf("%d,%d\n",lng,cnt);
    cnt++;
  }

  text=realloc(text,cnt*sizeof(char));
  print(text); /*prints all the lines*/

  return 0;
}

3 个答案:

答案 0 :(得分:5)

简短的回答是你不能直接分配内存,除非你知道分配多少。

但是,有多种方法可以确定您需要分配多少。

这有两个方面。一个是知道你需要处理多少个字符串。必须有一些明确的认识方式;要么你得到一个计数,要么有一些特定的指针值(通常是NULL)告诉你什么时候到达终点。

要将指针数组分配给指针,最简单的方法是计算必要指针的数量,然后分配空间。假设一个空终止列表:

size_t i;
for (i = 0; list[i] != NULL; i++)
    ;
char **space = malloc(i * sizeof(*space));
...error check allocation...

对于每个字符串,您可以使用strdup();你假设字符串格式正确,因此无效。或者您可以编写自己的strdup()类似物。

for (i = 0; list[i] != NULL; i++)
{
    space[i] = strdup(list[i]);
    ...error check allocation...
}

另一种方法是扫描指针列表一次,但多次使用malloc()realloc()。这可能总体上较慢。

如果您无法可靠地判断字符串列表何时结束或字符串本身何时结束,则您将被清除。完全彻底地冲洗。

答案 1 :(得分:1)

C没有字符串。它只是指向(通常以null结尾的)字符序列,并将它们称为字符串。

所以只需先分配一个指针数组:

 size_t nbelem= 10; /// number of elements
 char **arr = calloc(nbelem, sizeof(char*));

你真的想要calloc,因为你真的希望清除那个数组,因此每个指针都有NULL。当然,您测试calloc成功了:

 if (!arr) perror("calloc failed"), exit(EXIT_FAILURE);

最后,填充数组的一些元素:

 arr[0] = "hello";
 arr[1] = strdup("world");

(不要忘记free strdup的结果和calloc的结果。

您可以使用realloc增加数组(但我不建议这样做,因为当realloc失败时,您可能会丢失数据)。您可以通过分配更大的副本,将其复制到内部并重新定义指针来简单地增长它,例如

 { size_t newnbelem = 3*nbelem/2+10;
   char**oldarr = arr;
   char**newarr = calloc(newnbelem, sizeof(char*));
   if (!newarr) perror("bigger calloc"), exit(EXIT_FAILURE);
   memcpy (newarr, oldarr, sizeof(char*)*nbelem);
   free (oldarr);
   arr = newarr;
 }

不要忘记在Linux上使用gcc -Wall -g进行编译(在没有给出警告的情况下改进代码),并学习如何使用gdb调试器和valgrind内存泄漏检测器

答案 2 :(得分:0)

在c中,您无法直接分配字符串数组。您应该使用指向char数组的指针将其用作字符串数组。所以使用

char* strarr[length];

并保留角色阵列 你可以采取这样的方法:


  1. 通过调用malloc()
  2. 分配一块内存
  3. 跟踪输入的大小
  4. 如果您需要增加缓冲区大小,请致电realloc(ptr,size)