【问题标题】:Using calloc() to set up char array, also "freeing" array when done使用 calloc() 设置 char 数组,完成后也“释放”数组
【发布时间】:2014-06-21 19:24:00
【问题描述】:

我正在尝试设置一个字符串数组(在 C 中,使用 Linux)。该数组将包含 11 个字符串(静态长度)。我最初将数组设置为:

char Answers[10][100];

但在我的代码中,我有一部分调用 fgets(input,sizeof(input),stdin)。当这个 fgets() 部分被调用时,我的 Answers 数组的最后一个元素被输入的值覆盖(关于 Answers 在堆栈上的位置?)。所以现在我正试图“锁定”我用于 Answers 数组的内存。我会用吗

char Answers=calloc(11*sizeof(char));

通过循环运行它--

char Answers[10];
for(c=0;c<=10;c++)
{
    Answers[c]=calloc(1*sizeof(char);
}

另外,完成后我需要使用 atexit() 来释放分配的内存......因为我无法在 atexit() 中传递参数,所以最好的方法是什么?

atexit(Free);

void Free()
{
    free(Answers);
}

提前致谢!

【问题讨论】:

  • 如果它需要容纳11个字符串,为什么要指定“10”?
  • 1) calloc 不会“锁定”任何东西。 2)在进程退出之前释放内存是没有意义的。 3)你的数据被覆盖的原因是你用错误的参数调用fgets
  • “当这个 fgets() 部分被调用时,我的 Answers 数组的最后一个元素被输入的值覆盖” - 你应该做的是找出为什么会被覆盖并修复它,因为它几乎可以肯定是代码中的错误导致未定义的行为。
  • 为什么calloc只有一个参数?
  • “当这个 fgets() 部分被调用时,我的 Answers 数组的最后一个元素被覆盖了”——实际上并没有;但是您正在阅读数组的末尾。您的数组有 10 行,因此当您尝试读取第 11 行时,您碰巧读取了数组之后位于内存中的内容。您现有的Answers 定义没有问题。

标签: c arrays free calloc atexit


【解决方案1】:

好吧,我猜有很多误解。那里的大多数代码都是不正确的。 您要求输入 11 个字符串,因此 char Answers[10][100]; 不正确,您应该输入 char Answers[11][100];,这就是它跳过输入的原因。 关于错误... 首先 - calloc() 有两个参数而不是一个,例如 malloc(),如下签名所示:

void *calloc(size_t nmemb, size_t size);

void* 返回到分配的内存区域,第一个参数是您要分配的元素数量,第二个参数是每个元素的大小。 其次,如上键入,它返回一个 POINTER,一个 void 的,所以你不能正确执行这段代码:

char Answers[10];
for(c=0;c<=10;c++)
{
    Answers[c] = calloc(11*sizeof(char));
}

有什么问题?首先,参数,如前所述。但第二个事实是您根据需要制作了一个字符数组而不是 CHAR POINTERS。应该是这样的:

char* Answers[11]; //As you requested 11 elements
for(c=0;c<=10;c++)
{
    Answers[c] = (char*) calloc(1, MY_STR_LENGTH);
}

当 MY_STR_LENGTH 是常数 100 时,如您的示例所示。我们在 void 指针上使用了强制转换,我们更正了 calloc 的使用和 char 指针的声明。现在这段代码是正确的——另外,你为什么使用calloc?通常不需要在字符串中这样做。 顺便说一句,无论如何,当它是一条线时就不需要函数。 第二种声明方式是这样的:

char **Answers = calloc(11, sizeof(char*));
for(i = 0 ; i < 11 ; i++)
{
   Answers[i] = calloc(1, sizeof(char)*MY_STRING_LENGTH); //Basically it is MY_STRING_LENGTH as sizeof(char) is almost always one, but it's there only for the readability of the code.
}

就是这样,希望你能理解。 在此处阅读有关 C 中内存分配的更多信息:

About malloc() About calloc() About realloc()

【讨论】:

  • 您能解释一下为什么要为每一行分配11 * MY_STRING_LENGTH 字节,而不仅仅是MY_STRING_LENGTH 吗?
  • @MatMcNabb 知道不需要强制转换 calloc (我这样做只是为了,让我们在代码中说“逻辑”)但我真的不知道它可以隐藏错误,谢谢启发,我在代码中更正了它。关于分配,确实,我的糟糕XD是晚上在我家,所以我真的没有那么专注。也更正了。谢谢
  • @user3195614,这里已经很晚了,所以我今晚无法实现它,但我会在明天首先尝试。谢谢您的帮助! (不能投票,因为我是新人,但认为这是早期的赞许)。
  • @Katarn 有帮助吗?
猜你喜欢
  • 1970-01-01
  • 2011-08-20
  • 1970-01-01
  • 1970-01-01
  • 2019-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多