【问题标题】:free(): invalid next size (normal) while executing freefree(): 执行 free 时下一个大小无效(正常)
【发布时间】:2019-09-01 20:14:31
【问题描述】:

我正在学习 c 编程。下面的程序向我展示了输出,但是当它执行 free 方法时。这是给我错误:- 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 != '\0') {
            d++;
        }
        while (*s != '\0') {
            *d++ = *s++;
        }
        *d = '\0';
    }

【问题讨论】:

  • 您最多读取 1024 个字节,然后将其连接到缓冲区。这很容易超过缓冲区的大小。例如,如果缓冲区中当前有 700 个字节,并且您连接 800 个字节,那么您将在缓冲区中放入 1500 个字节。这会溢出缓冲区并破坏内存中的其他数据。在将数据放入其中之前,请确保缓冲区足够大以容纳数据,而不是之后。另外,请注意您的计数是否包括终止空字符。如果您将 1024 个非空字符和一个终止空字符放入一个 1024 字节的缓冲区,那么您已经超出了它。
  • 埃里克·波斯托伊希尔。我正在检查大小并使用 realloc 扩展大小。它随机抛出此错误。
  • 您更改了问题中的代码。现在这是一个不同的问题。
  • @Vipin 你试过在 valgrind 和/或 address sanitizer 下运行它吗?
  • Eric Postpischil 是的,你是对的,我更新了代码。即使在这两种情况下,它都会引发相同的错误。这是我粘贴代码时的错误。

标签: c gnu


【解决方案1】:
  1. 在现代 C 中,例程必须在使用前声明。要么将concat 的定义移到main 之前,要么在main 之前插入concat 的声明。

  2. int main() 更改为int main(void)

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

  4. if (totallengthread &gt;= alloc_size) 不考虑空终止符。将其更改为if (totallengthread+1 &gt;= alloc_size)`。

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

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

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

  8. 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 ,非常感谢,这对我帮助很大。我正在学习c编程。你的 cmets 对我理解我的错误帮助很大。
【解决方案2】:

附上 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] = '\0';
        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 != '\0') {
        d++;
    }
    while (*s != '\0') {
        *d++ = *s++;
    }
    *d = '\0';
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-28
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多