【问题标题】:C - list of char*'s - Memory AllocationC - char* 的列表 - 内存分配
【发布时间】:2014-10-03 05:50:06
【问题描述】:

我对如何正确分配内存感到困惑。我正在尝试从文本文件中列出 char*。每次我制作一个 char* 时,我都必须为它分配内存吗?何时何地有例外情况?

#define BUFF 1000   

 int main(int argc, char** argv)
 {
  FILE* file;
    file = fopen(argv[1], "r");
    char* word = calloc(BUFF, sizeof(char));
    char* sentence = calloc(BUFF, sizeof(char));
    char** list = calloc(BUFF, sizeof(char*));
    int i = 0;
while((fgets(sentence, BUFF, file)) != NULL)
{
  word = strtok(sentence, " ,/.");
  while(word != NULL)
  { 
    printf("%s\n", word);
    strcpy(list[i],  word);
    i++;
    word = strtok(NULL, " ,/.");
  } 
}
int k;
for(k = 0; k < i; k++)
{
 puts("segging here");
 printf("%s\n", list[i]);
}

【问题讨论】:

  • 这是#define BUFF 1000 抱歉
  • 一个建议:调用BUFF 类似BUFFER_SIZE 以使其含义更明确。
  • 或 BUFLEN 以保持简洁。但是,在所有这些情况下使用相同的常量并不是一个好主意……BUFLEN、WORDLEN、SENTENCELEN、MAXWORDS 都是不同的概念。如果你要使用固定大小的数组,你应该尽量不要溢出它们。

标签: c memory char


【解决方案1】:

规则是:你必须分配你使用的任何内存。

你的问题来了:

strcpy(list[i],  word);

list[i] 当前没有指向任何已分配的存储空间(它可能是一个空指针)。您必须先将其指向某个位置,然后才能将字符复制到其中。

一种方法是:

list[i] = strdup(word);

strdup 不是 ISO C 标准函数,但相当于先做malloc 然后strcpy。之后您需要free

另外,i++ 行需要在i == BUFF 时停止,将\n 添加到strtok 分隔符列表会很有用。

【讨论】:

  • 感谢 matt 的回复 - 只是为了澄清一下:我只是为 char** 指针分配了空间,而不是当我在 list 上调用 calloc 时它指向的单个 char* ?因此,当我调用 calloc 时,我只是说该列表具有指向单个 char* 的内存,但 char* 本身没有分配?这就是为什么我还必须分配单个 char*s?
  • @user3312266 没错。将 calloc 的结果分配给列表后,所有char*s 都是 0 位(在许多但不是所有实现上都是 NULL)。您必须为它们分配一个值(您没有这样做),并且该值需要是指向某处内存的指针。
【解决方案2】:

除了马特麦克纳布的回答之外,您对strtok 的使用还有一个更微妙的问题。该功能不需要输出缓冲区;它只是返回一个指向输入缓冲区内某处的指针。

当您调用char* word = calloc(BUFF, sizeof(char)); 时,您分配内存并分配word 以指向分配的内存。然后,当您调用word = strtok(sentence, " ,/."); 时,您会覆盖word 的值。这意味着您的控件中没有指针指向您分配的内存。该内存不再对您的代码有用,并且您无法释放它;已经泄露了。

你可以通过写char* word = strtok(sentence, " ,/.");来解决这个问题然后,由于你没有分配word指向的内存,记住也不要free它。

【讨论】:

  • 但是给word赋值,而不先分配内存,为什么不会导致未定义的行为?
  • @user3312266 您正在分配一个指向sentence 的指针(这就是strtok 返回的内容),它已分配。指针在取消引用之前必须包含有效地址,但该地址不必重新分配,它可以是指针类型的任何有效地址。
【解决方案3】:

您的list 是一个char* 列表,大小为BUFF,但list[i] 是什么? 你不分配内存给它。

你需要在循环中为list[i]分配内存

【讨论】:

    猜你喜欢
    • 2015-09-25
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 2014-11-02
    • 2013-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多