始终检查malloc';有记忆吗?

始终检查malloc';有记忆吗?,c,architecture,system,C,Architecture,System,我经常发现自己在做以下事情(在非关键组件中): 换句话说,我为一个小结构动态分配内存,直接使用它而不检查malloc'ed指针。我知道,总是有一个机会,程序不会得到它所要求的内存(Duh!),但是考虑以下内容: 如果程序甚至不能为一个小结构从服务器上获取一些内存 堆,也许有更大的问题迫在眉睫,这根本不重要 此外,如果处理空指针会进一步加剧不稳定的情况呢??(例如,尝试记录条件调用更多不存在的资源等) 我的推理是否合理(足够) 已更新: “safe_malloc”函数在调试时很有用,在其他情况下也

我经常发现自己在做以下事情(在非关键组件中):

换句话说,我为一个小结构动态分配内存,直接使用它而不检查malloc'ed指针。我知道,总是有一个机会,程序不会得到它所要求的内存(Duh!),但是考虑以下内容:

如果程序甚至不能为一个小结构从服务器上获取一些内存 堆,也许有更大的问题迫在眉睫,这根本不重要

此外,如果处理空指针会进一步加剧不稳定的情况呢??(例如,尝试记录条件调用更多不存在的资源等)

我的推理是否合理(足够)

已更新

  • “safe_malloc”函数在调试时很有用,在其他情况下也可能有用
  • +X
    access可以隐藏空指针的根本原因
  • 在Linux上,“乐观内存分配”可以在OOM(内存不足)条件下隐藏内存

  • 至少我会在其中放入一个
    断言(ptr!=NULL)
    ,这样您就可以得到一个有意义的错误。

    启动时可以分配一个较大的内存块,当您遇到内存不足的情况时可以释放它,并使用它优雅地关闭

    此外,如果处理空指针会进一步加剧不稳定的情况呢

    我不明白为什么它会使情况恶化。
    无论如何,在为windows ptr->编写代码时,某些_成员将抛出访问冲突,因此您将立即看到问题,因此我认为没有理由检查返回值,除非您的程序有机会释放内存。 对于不能很好地处理空指针的平台(抛出异常),忽略这些点是危险的。

    我会说不。 使用空指针将导致程序崩溃(可能)。
    但是检测它并做一些智能化的事情是可以的,你可以从内存不足的情况中恢复过来

    如果要执行大型操作,请设置一些全局错误标志,然后开始展开堆栈并释放资源。希望这些资源中的一个或多个会占用您的内存,您的应用程序将恢复正常

    <>这当然是C问题,在异常和RAII的帮助下自动在C++中进行手工处理。
    因为new不会返回NULL,所以检查没有意义。

    对于C,它取决于平台。如果你在一个内存很少的嵌入式平台上,你应该经常检查,尽管如果它真的失败了,你该怎么办更难说。在具有虚拟内存的现代32位操作系统上,系统可能会在承认内存不足之前失去响应并崩溃。在这种情况下,对malloc的调用永远不会返回,因此检查其值的实用程序变得毫无意义


    在C++的情况下,你应该使用新的代替Malc,这样在耗尽时会引发异常,所以检查返回值没有意义。

    < P>是的,内存不足会几乎预示着其他故障即将到来。strong>但是您有多确定在分配失败和最终崩溃之间不会出现损坏的输出

    每次编辑时,您对每个程序都有多大把握


    捕捉您的错误,以便知道您已按时崩溃。

    取决于平台。例如,在Linux上(默认情况下),检查NULL没有多大意义:

    默认情况下,Linux遵循乐观的内存分配策略。这意味着当malloc()返回非NULL时,无法保证内存确实可用。这是一个非常糟糕的错误。如果系统内存不足,一个或多个进程将被臭名昭著的OOM杀手杀死


    我总是觉得处理malloc的返回或任何其他系统调用是很重要的,也是最好的。尽管在现代系统中(除了嵌入式系统),除非代码使用了太多内存,否则这种情况很少发生,但它总是更安全的

    在系统调用失败后继续执行代码可能会导致损坏、崩溃以及其他问题,这不仅会使程序看起来很糟糕

    此外,在linux中,分配给进程的内存是有限的。尝试在一个进程中创建1000个线程,并在每个线程中分配一些内存,这样就可以轻松模拟内存不足的情况。:)


    最好检查系统调用返回值

    假设您正在Linux/MaxOs/Windows或其他虚拟内存系统上运行,那么。。。检查malloc返回值的唯一原因是您是否有释放足够内存以允许程序继续运行的策略。信息性消息将有助于诊断问题,但仅当程序导致内存不足时。 通常这不是你的程序,你的程序能做的唯一帮助就是尽快退出

    assert(ptr != NULL);
    
    我会做所有这些事情。我通常的策略是在malloc周围有一层 这个在里面

    void *my_malloc(size_t size)
    {
        void *ptr = malloc ( size );
        assert(ptr != NULL);
        return *ptr;
    }
    

    然后你叫我的马洛克而不是马洛克。在开发过程中,我使用了一个有利于调试的内存分配库。之后,如果内存不足,我会收到一条消息。

    分配可能会失败,原因有几个。您对此所做的(以及能够做的)部分取决于分配失败

    真正失去记忆是灾难性的。除非你对此做了仔细的计划,否则你可能无能为力。(例如,您可以预先分配紧急保存和关机所需的所有资源。)

    但许多分配失败与内存不足无关。碎片可能导致分配失败,因为即使有大量可用内存,也没有足够的连续可用空间。这个问题特别提到了一个“小结构”
    void *my_malloc(size_t size)
    {
        void *ptr = malloc ( size );
        assert(ptr != NULL);
        return *ptr;
    }