C语言 在 malloc 之后调用 free() 会导致意外行为



嗨,我读到我应该尽快调用free()以释放内存,但是当我以这种方式调用free时,我的代码停止正常工作。 问题出在哪里?

我想在每次迭代和发生错误时调用free()

int read_words(char *words[], int size, int max_str_len) {
int i, j;
char *ExtendedWord = NULL;
for (i = 0; i < size && size != -1; ++i) {
char tmp[1], ch, *word = tmp;
for (j = 0; j < max_str_len; ++j) {
if (scanf("%c", &ch) == EOF || ch == 'R') {
size = -1;
break;
}
if (ch == ' ')
break;
word[j] = ch;
ExtendedWord = malloc((i + 2) * sizeof(char));
if (ExtendedWord == NULL)
return -1;
strcpy(ExtendedWord, word);
word = ExtendedWord;
free(ExtendedWord);
}
word[j] = '';
words[i] = word;
}
return i;
}
strcpy(ExtendedWord,word);

strcpy()期望将"C"字符串的第一个字符的地址作为第二个参数,该字符串实际上是一个char数组,至少有一个元素等于''

word指向的内存不符合此类要求。

因此,会调用臭名昭著的未定义行为,可能会弄乱程序的内存管理,进而导致free()失败。

代码中存在多个问题:

  • 您可以释放新分配的块而不是前一个块。
  • 你不 null 在将字符串传递给strcpy之前终止字符串
  • word应初始化为NULL或分配给的内存块,而不是指向无法传递给free()的本地数组。
  • 您应该复制数组末尾的新字符之前重新分配数组。

这是一个修改版本:

int read_words(char *words[], int size, int max_str_len) {
int i, j;
for (i = 0; i < size; i++) {
char *word = malloc(1);
if (word == NULL)
return -1;
for (j = 0; j < max_str_len; ++j) {
int ch;
char *ExtendedWord;
if ((ch = getchar()) == EOF || ch == 'R') {
size = -1;
break;
}
if (ch == ' ' || c == 'n')
break;
/* reallocate array for one more character and a null terminator */
ExtendedWord = malloc(i + 2);
if (ExtendedWord == NULL)
return -1;
memcpy(ExtendedWord, word, i);
free(word);
word = ExtendedWord;
word[j] = ch;
}
if (size == -1) {
free(word);
break;
}
word[j] = '';
words[i] = word;
}
return i;
}

我读到我应该尽快调用free((以释放内存

这种描述有点模棱两可。 只有当您将"尽快我能做到这一点"解释为与"一旦我不再需要分配的内存"相同时,这是合理的。

但是当我以这种方式调用free时,我的代码停止正常工作。 有什么问题?

关于free的问题在于,您在完成内存之前释放内存。 随后尝试访问该内存会产生未定义的行为。

代码还有其他问题,在其他答案中也有讨论,但这就是free适应图片的方式。

我想在每次迭代和发生错误时调用 free。

由于您的函数似乎打算通过words数组向其调用方提供指向已分配内存的指针,因此您不得在函数范围内的任何地方释放该内存,因为调用方(必须假定(打算使用它。 因此,调用方必须承担释放它的责任。 函数的文档应清楚地描述该责任。

也许这里会出现混淆:

word=ExtendedWord;

必须了解赋值复制指针,而不是它指向的空间。 之后,word指向与ExtendedWord相同的(动态分配的(空间,因此释放ExtendedWord会使指针的两个副本无效。

相关内容

  • 没有找到相关文章

最新更新