【问题标题】:malloc() function crashesmalloc() 函数崩溃
【发布时间】:2014-04-13 15:33:30
【问题描述】:

我有一个程序,我正在从 txt 文件中读取数据。 它基本上是每行中的(固定在第一行)整数个数。

例子:

    11
    1 0 0 1 0 0 0 0 0 2 0
    0 0 0 0 0 0 0 1 2 0 0
    0 0 0 0 0 0 3 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 

我可以毫无问题地将它们读入 int-Pointer 并将这个指针传递给另一个函数:

    Term initTerm(int size, int* Exponents){
         Term a = newTerm(size)
         //Some code to insert the int's of the pointer into the pointer of Term
         return a
    }

    typedef struct Term{
        int* Exponents; 
        int size;       //Number of ints in the Exponents-pointer
    }Term;

    Term newTerm(int size){
        Term res;
        res.Exponents = malloc(size*sizeof(int));
        //Check for NULL
        res.size = size;
        return res;
    }

现在的问题如下: 在 194 次完全正确的 initTerm 调用之后,第 195 次调用使程序崩溃。 调试确定,失败发生在 malloc 调用中(而不是检查返回的指针的有效性)。 如果我更改调用 initTerm 的代码顺序,我只能达到 Term ~300,对于一些编译标志,例如 -O3 或 -pg(我正在使用 gcc-Compiler)也是如此,更改正确调用的数量.

我已经发现,如果额外分配的头部损坏,malloc() 会崩溃,这通常是由多线程引起的。由于我的程序在每一行代码中都是完全单线程的,我想知道我能做些什么来阅读整个文件(目前是 710 个术语,可能增长到几兆字节)

编辑: 感谢您的帮助,我发现了问题。 关于 malloc-Failure 只是症状的说法是对的,因为我刚刚意识到我用来将文件中的行放入的缓冲区从未重置,因此开始在我的 RAM 中的任何地方徘徊。复制地址,malloc 返回,到一个指针并在提取数字后重置缓冲区,现在可以正常工作了!

【问题讨论】:

  • 我敢打赌,您正在代码中的其他部分访问(写入)越界元素。检查用于访问已分配数组的所有索引。您可能想要使用函数 setExponent(struct Term base, int index, int value) 并使用它,with checks,而不是直接访问。
  • 错误发生在malloc的执行中,而不是访问int。这就是在 newTerm() 中使用 printf 进行调试的结果。尽管如此,我还是会做 setExponent-Function,谢谢你的想法!
  • @T-r4X 您说错误发生在 malloc 的执行中,但是我认为 pmg 的意思(以及我根据您的描述相信)是错误的——而是 symptom 发生在 malloc 的执行中,error 发生得更早,没有直接后果。正如 pmg 建议的那样,您可能正在写入您无权访问的内存空间,这会破坏 malloc 内部使用的结构,从而导致崩溃。
  • malloc 中的崩溃几乎总是早期错误写入分配内存范围之外的结果。堆损坏错误难以追踪的主要原因之一是明显症状(崩溃)的位置通常远离根本原因的位置。

标签: c pointers crash malloc


【解决方案1】:

看起来像标准内存损坏通过缓冲区溢出、释放内存的使用、野指针的使用等,尽管它不在提供的代码中。
malloc() 只会在簿记数据结构时崩溃已损坏(可能)或实现有问题(如果您不自己动手,则极不可能)。

使用带有附加检查的 debug_malloc 或像 valgrind 这样的检查器。您可以考虑在有趣的点插入完整的堆检查。

【讨论】:

  • 缓冲区溢出是否在确定的基础上发生?没关系,其他程序使用了多少 RAM,TaskManager 不会显示任何 MemoryLeak 或任何与此相关的内容
  • 取决于您的代码在此之前是否具有确定性;-) 无论如何,只需建立一个完整的堆检查机制,并使用调试堆。
  • 缓冲区溢出与内存泄漏或外部程序使用的 ram 无关。它们可以是确定性的,也可以不是确定性的,取决于执行它们的代码。有时它们是由未定义的行为引起的,而另一些则是由于忽略了一些简单的事情。你最好的选择是使用内存调试器工具,例如 Valgrind,如果你的系统支持的话(大多数,如果不是所有系统,都有可用的东西)。
猜你喜欢
  • 2011-11-24
  • 2011-08-13
  • 1970-01-01
  • 2014-05-06
  • 2014-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-02
  • 2015-05-28
相关资源
最近更新 更多