Realloc搞砸了代码

时间:2017-05-14 04:02:36

标签: c

我写了一个程序,它应该在文件中进行查找和替换,条件是新单词必须比旧单词长。我有很多问题,比如打印奇怪的字符,或者核心转储,但当我删除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);
}

1 个答案:

答案 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返回的新内存开头的引用。