3

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

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

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

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

我想尽可能多地自己弄清楚,因此没有发布实际代码。但是,如果这些都没有任何意义,我会发布它。

编辑:这是代码

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

3 回答 3

5

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

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

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

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

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

对于每个字符串,您可以使用strdup(); 您假设字符串格式正确,因此以 null 结尾。或者您可以编写自己的strdup().

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

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

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

于 2012-11-12T20:32:27.100 回答
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;
 }

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

于 2012-11-12T20:30:26.573 回答
0

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

char* strarr[length];

并保持字符数组您可以采用以下方法:


  1. 通过调用分配一块内存malloc()
  2. 跟踪输入的大小
  3. 当您需要增加缓冲区大小调用时realloc(ptr,size)
于 2012-11-12T20:31:34.600 回答