Realloc把代码搞乱了
我写了一个程序,应该在一个文件中进行查找和替换,条件是新词必须比旧词长。我对它有很多问题,比如打印奇怪的字符,或者转储内核,但是当我删除Realloc把代码搞乱了,c,C,我写了一个程序,应该在一个文件中进行查找和替换,条件是新词必须比旧词长。我对它有很多问题,比如打印奇怪的字符,或者转储内核,但是当我删除realloc语句时,问题似乎就消失了。我不太熟悉这个函数,我犯了什么错误 还有,我的空闲时间应该在哪里 void replace_word(const char *s, const char *old_word, const char *new_word){ char *buffer = malloc(BUFFER_SIZE); char *i
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);
}
realloc
获取指向动态分配内存的指针,并调整内存块的大小。缺乏动态内存经验的人经常忽略的一点是,realloc
返回的指针可能与传入的指针不同(通常不是)。通常,堆没有足够的连续内存来执行请求的扩展,因此它会找到一个足够大的新内存块来容纳它,并将以前的内容复制到内存中
关于您的代码,我注意到的第一件事是您执行了一个不安全的realloc
:
buffer = realloc(buffer, BUFFER_SIZE + new_word_len - old_word_len);
通过将指针分配到自己的realloc
,操作系统可能无法完成分配并返回NULL
。如果发生这种情况,您将丢失指向旧内存的指针,并且您的手上存在内存泄漏。要正确地realloc
(我猜您无论如何都需要这样做来修正我的下一点),请将realloc
的结果分配给另一个指针,确认它不是NULL
,然后覆盖指针
但我认为您的代码的主要问题在于:
buffer = init;
如果我理解正确,此语句的目的是将
buffer
返回到字符串的开头。但是,init
指向的内存已被realloc
释放,您最终取消了对悬挂指针的引用。您需要存储一个引用,指向由realloc
src=tmp+old\u word\n返回的新内存的开头代码>:tmp
指向地址的点是realloc
memmove(dst、src、strlen(src))之前的地址代码>-->memmove(dst、src、strlen(src)+1)代码>buffer=init代码>:init
是旧的缓冲区。您不能使用指向重新分配的空间的任何指针(即使realloc恰好指向同一位置)。这里最好使用整数偏移量。问题是,您假设一旦您执行realloc,tmp将保持有效,而这可能不是。谢谢。它最终似乎起作用了,我所做的是在if
中创建第二个指针,并使用malloc
而不是realloc
,然后将旧的缓冲区复制到其中。我不确定realloc是否会扩展当前的块或创建一个新的块,文档也不清楚。这个解决方案可能很好realloc
根据旧指针上有多少连续内存可用,展开或创建一个新指针。如果必须创建新块,它会将旧块中的所有内容复制到新块的开头。