free():执行 free 时无效的下一个大小(正常)

free(): invalid next size (normal) while executing free

我正在学习c编程。下面的程序向我展示了输出,但是当它执行自由方法时。它给我错误:- free(): invalid next size (normal) 。请让我知道我缺少什么。

 #include<stdio.h>
    #include<stdlib.h>
    int main() {

        FILE *fp;

        char r[1024];
        fp = popen("/bin/ls /etc/", "r");

        if (fp == NULL) {
            perror("Failed to run the command");
            exit(-1);
        }

        int totallengthread = 0, alloc_size = 1024;
        char *buffer = (char*) calloc(alloc_size , sizeof(char));
        int lenofbuff = 0;
        while((lenofbuff=fread(r,sizeof(char),1024,fp))>0){

            totallengthread += lenofbuff;
                    if (totallengthread >= alloc_size) {
                        alloc_size += 1024;
                        buffer = realloc(buffer, alloc_size);
                    }
            concat(buffer, r);
        }
        printf("this is the output =>%s", buffer);
        pclose(fp);
        free(buffer);
        return 0;
    }
    void concat(char *dest, const char *source) {
        char *d = dest;
        char *s = source;
        while (*d != '[=10=]') {
            d++;
        }
        while (*s != '[=10=]') {
            *d++ = *s++;
        }
        *d = '[=10=]';
    }
  1. 在现代 C 中,例程必须在使用前声明。在 main 之前移动 concat 的定义,或者在 main.

  2. 之前插入 concat 的声明
  3. int main()更改为int main(void)

  4. fread 不会为读取的数据添加空终止符。将 char r[1024]; 更改为 char r[1025]; 并在 fread 之后插入 r[lenofbuff] = '[=19=]'; 作为 while 正文中的第一个语句。

  5. if (totallengthread >= alloc_size) 不考虑空终止符。将其更改为 if (totallengthread+1 >= alloc_size)`。

  6. concat中,将char *s = source;更改为const char *s = source;

  7. 打开编译器警告并注意它们。他们应该就上面的 1 和 5 警告过你。

  8. char *buffer = (char*) calloc(alloc_size, sizeof(char));后,测试buffer == NULL。如果是,则打印错误并退出。此外,此语句的更好形式是 char *buffer = calloc(alloc_size, sizeof *buffer);。在 C 中不需要强制转换 calloc 的结果,并且如果将来更改类型,则将大小基于正在分配的事物而不是重复类型可能更安全。

  9. buffer = realloc(buffer, alloc_size);更改为char *temp = realloc(buffer, alloc_size * sizeof *buffer); if (temp == NULL) { print message and exit } else buffer = temp;

附上 Eric Postpischil 建议的更正代码。现在一切正常。

#include<stdio.h>
#include<stdlib.h>
void concat(char *dest, const char *source);
int main(void) {
    FILE *fp;
    char r[1024];
    fp = popen("/bin/ls /etc/", "r");

    if (fp == NULL) {
        perror("Failed to run the command");
        exit(-1);
    }

    int totallengthread = 0, alloc_size = 1024;
    char *buffer = (char*) calloc(alloc_size, sizeof(char));
    if (buffer == NULL) {
        perror("Failed allocate memory");
        exit(-1);
    }
    int lenofbuff = 0;
    while ((lenofbuff = fread(r, sizeof(char), 1023, fp)) > 0) {
        r[lenofbuff] = '[=10=]';
        totallengthread += lenofbuff;
        if ((totallengthread) >= alloc_size) {
            alloc_size += 1024;
            buffer = realloc(buffer, alloc_size*sizeof(char));
            if (buffer == NULL) {
                perror("Failed to extend  memory");
                exit(-1);
            }
        }
        concat(buffer, r);

    }
    printf("this is the output =>%s", buffer);
    pclose(fp);
    free(buffer);
    return 0;
}
void concat(char *dest, const char *source) {
    char *d = dest;
    const char *s = source;
    while (*d != '[=10=]') {
        d++;
    }
    while (*s != '[=10=]') {
        *d++ = *s++;
    }
    *d = '[=10=]';
}