【问题标题】:Error in 'a.out': free(): invalid next size (normal)“a.out”中的错误:free():下一个大小无效(正常)
【发布时间】:2014-10-30 19:39:44
【问题描述】:

我正在编写一个大型应用程序,并且我最近在其中包含了用于处理文件的新模块。它具有写入整数和字符串的简单功能,在 Red Hat 上测试完美。它完全符合我的要求。

这里是函数的实现:

int CFile_open(CFile* owner, char* filename, char* mode) {
    owner->file = fopen(filename, mode);
    if (owner->file == NULL) {
        return 0;
    } else {
        return 1;
    }
}

int CFile_close(CFile* owner) {
    if (owner->file == NULL) {
        return 0;
    } else {
        if (fclose(owner->file) ) {
            return 1;
        } else {
            return 0;
        }
    }
}

int CFile_writeInt(CFile* owner, int num) {
    if (owner->file == NULL) {
        return 0;
    } else {
        if (fwrite(&num, sizeof(int), 1, owner->file)) {
            return 1;
        } else {
            return 0;
        }
    }
}

int CFile_writeString(CFile* owner, char* str) {
    if (owner->file == NULL) {
        return 0;
    } else {
        char b = strlen(str);
        if (fwrite(&b, sizeof(char), 1, owner->file)) {
            for (int i=0; i<=b; i++) {
                fwrite(&str[i], sizeof(char), 1, owner->file);
            }
        } else {
            return 0;
        }
    }
}

这些函数在包装函数中使用,然后在我的应用程序中执行。
这是那个函数:

void fileWrite(void* data) {
    CList* list = (CList*)data;
    CNode* node = list->first;
    CData* info = NULL;
    CFile* f = (CFile*)malloc(sizeof(CFile));
    f->init = CFile_init;
    f->init(f);

    if (list->length == 0) {
        printf("%s\n", "The list is empty!");
        wait();
    } else {
        int i = 1;

        if (f->open(f, (char*)"./f", (char*)"w")) {
            while (node) {
                info = node->getData(node);

                if (f->writeInt(f, info->getNum(info))) {
                    if (f->writeString(f, info->getAdr(info))) {
                        if (f->writeString(f, info->getPh(info))) {
                            printf("%s%d\n", "Wrote item #", i);
                            i++;
                        } else {
                            printf("%s%d\n", "Error writing Phone of item #", i);
                        }
                    } else {
                        printf("%s%d\n", "Error writing Adress of item #", i);
                    }
                } else {
                    printf("%s%d\n", "Error writing Number of item #", i);
                }

                node = node->next;
            }
            if (f->close(f)) {
                printf("%s\n", "Wrote successfully");
                wait();
            }
        }
        free(f);
    }
}

有问题的地方是函数末尾的f-&gt;close(f)
如果我不关闭文件,一切都会完美无缺。但如果我这样做,我会收到以下错误:

*** Error in 'a.out': free(): invalid next size (normal): 0x0859c320 ***

然而,尽管应用程序崩溃了,它确实关闭了文件,而且我写给它的信息是正确的并且没有损坏。

但我不知道为什么会出现错误。我只关闭了一次文件(正如您从函数中看到的那样),我还尝试评论 free(f) 行。
另外,如果我打电话给fclose(f-&gt;file),我会得到同样的错误,所以这不是close() 函数问题。

我假设应用程序的其余部分可以正常工作(并且在我添加函数之前工作)除了我关闭文件的那一行。

我提到 RedHat 的原因是因为它在那里工作得很好,但是当我在 ArchLinux 下重新编译它(也尝试过 Debian)时 - 它不会关闭文件。到处都使用相同的编译器版本。

如果这很重要,我会用g++ 编译它,但我也有与clang++ 相同的问题。

我还尝试使用valgrind 运行它,但它没有说明文件,或者我只是找不到正确的键。也许你知道?

那么您对正在发生的事情以及如何解决它有任何想法吗?我已经盯着代码 3 个小时了,我一辈子都想不通。


测试用例:

info-&gt;getNum() 返回整数“11”(在输入期间分配)
info-&gt;getAdr() 返回动态分配的字符数组“aa”(在输入期间分配和分配)
info-&gt;getPh() 返回动态分配的字符数组“bb "(在输入时分配和分配)

我可以在我的应用程序中使用其他函数来测试这些值,因此我 100% 确信它们是正确的。

然后我就调用fileWrite() 函数。

【问题讨论】:

  • 展示你的测试用例
  • 如果不了解CFile 成员函数的作用,就很难提出有用的建议。
  • 编辑了问题。我不知道这是否有帮助,因为我从函数外部得到的唯一东西是我可以检查的值,我确信它们是正确的。
  • R Sahu,CFile 函数在帖子的第一个代码块中列出。
  • 如果注释掉while循环,只留下打开和关闭文件怎么办?

标签: c++ gcc file-io


【解决方案1】:

乍一看:

CFile_writeString 中存在一个错误。 for (int i=0; i&lt;=b; i++) 应在 i&lt;b 终止。 &amp;str[b] 将导致未定义的行为。

顺便说一句,strlen 的结果类型是 size_t,而不是 char

不过,我不知道这是否是您的问题的原因。

【讨论】:

  • 感谢您指出这一点。我修好了它。但是,显然,问题仍然存在。
  • 尝试使用-Wall -Wextra 进行编译以利用编译器诊断并修复所有警告。如果这仍然不能解决您的问题,请尝试将测试用例减少到重现问题所需的最小示例(请参阅http://stackoverflow.com/help/mcve)。
  • 我在 reddit 上看过你的帖子,并查看了 https://bitbucket.org/owyou/simplebd。另一个问题:您为 5 个菜单项预留了空间,但调用了 6 次 CMenu_addItem,导致另一个单独访问 owner-&gt;list[len]
  • 用列表修复一个消除了错误。感谢您的关注。当我还需要处理用户输入时,我总是对数组索引感到困惑。
  • 我有一个类似的问题,在这里检查了答案,发现我也有类似的边界问题。谢谢大家
猜你喜欢
  • 1970-01-01
  • 2015-04-16
  • 1970-01-01
  • 1970-01-01
  • 2019-08-06
  • 1970-01-01
  • 2012-10-23
  • 2012-10-25
  • 2012-05-22
相关资源
最近更新 更多