我写了一个程序,它应该在文件中进行查找和替换,条件是新单词必须比旧单词长。我有很多问题,比如打印奇怪的字符,或者核心转储,但当我删除realloc
语句时,问题似乎消失了。我对这个功能不太熟悉,我做了什么错误?
另外,我的自由应该在哪里吗?
void replace_word(const char *s, const char *old_word, const char *new_word){
char *buffer = malloc(BUFFER_SIZE);
char *init = buffer;
FILE *original_file;
FILE *copy;
if((original_file = fopen(s, "r")) == NULL){
perror(s);
exit(EXIT_FAILURE);
}
if((copy = fopen("copy.txt", "w")) == NULL){
perror("text");
exit(EXIT_FAILURE);
}
int old_word_len = strlen(old_word);
int new_word_len = strlen(new_word);
char *src;
char *dst;
char *tmp;
while(fgets(buffer, BUFFER_SIZE, original_file)){
if((tmp = strstr(buffer, old_word))){
buffer = realloc(buffer, BUFFER_SIZE + new_word_len - old_word_len);
src = tmp + old_word_len;
dst = tmp + new_word_len;
memmove(dst, src, strlen(src));
memcpy(tmp, new_word, new_word_len);
buffer = init;
}
fprintf(copy, "%s", buffer);
if(!strchr(buffer, '\n')){
fseek(original_file, -old_word_len, SEEK_CUR);
}
free(buffer);
buffer = malloc(BUFFER_SIZE);
}
free(buffer);
}
答案 0 :(得分:2)
realloc
获取指向动态分配的内存的指针并调整内存块的大小。对于动态内存经验不足的人来说,重要的一点是realloc
返回的指针可能与传入的指针不同(通常不是)。通常,堆没有足够的连续内存来执行请求的扩展,因此它会找到一个足够大的新内存块以适应它并复制先前的内容。
我注意到您的代码的第一件事是执行不安全的realloc
:
buffer = realloc(buffer, BUFFER_SIZE + new_word_len - old_word_len);
通过为其自己的realloc
分配指针,您可能会面临操作系统无法完成分配并返回NULL
的风险。如果发生这种情况,您已经丢失了指向旧内存的指针,并且手上有内存泄漏。要正确地realloc
(并且我猜测你还需要这样做才能解决我的下一个问题),请将realloc
的结果分配给不同的指针,确认它&#39 ; s不是NULL
,然后覆盖指针。
但我认为代码的主要问题在于:
buffer = init;
如果我理解正确,此语句的目的是将buffer
返回到字符串的开头。但是,init
指向的内存已被realloc
释放,最终取消引用悬空指针。您需要存储对realloc
返回的新内存开头的引用。