嗨,我读到我应该尽快调用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
会使指针的两个副本无效。