当前位置: 首页 > 面试题库 >

在C / C ++中处理内存不足情况的合适方法是什么?

鲁炳
2023-03-14
问题内容

我正在编写一个消耗大量内存的缓存应用程序。

希望我会足够好地管理内存,但是我只是在考虑如果内存用完了该怎么办。

如果分配一个简单对象的调用失败,那么即使是syslog调用也可能失败吗?

编辑:好的,也许我应该澄清这个问题。如果malloc或new返回NULL或0L值,则从本质上讲这意味着调用失败,并且由于某种原因它无法为您提供内存。那么,在这种情况下明智的做法是什么?

EDIT2:我刚刚意识到对“
new”的调用会引发异常。这可能会在更高层次上被发现,所以我也许可以优雅地退出。此时,根据释放的内存量,甚至有可能恢复。到那时,我至少应该希望能够记录一些内容。因此,尽管我看到了在new之后检查指针值的代码,但这不是必需的。在C语言中,应检查malloc的返回值。


问题答案:

好吧,如果您遇到分配内存失败的情况,那么您将获得一个std::bad_alloc例外。异常导致程序堆栈被取消缠绕。很有可能,应用程序逻辑的内部循环不会处理内存不足的情况,只有应用程序的更高级别可以这样做。由于堆栈即将解开,因此将释放大量内存-
实际上,它应该几乎是程序所使用的所有内存。

一个例外是当您请求无法满足的很大(例如几百MB)内存块时。但是,当发生这种情况时,通常会剩下足够小的内存块,这将使您能够优雅地处理故障。

堆栈展开是您的朋友;)

编辑: 刚意识到这个问题也用C标记了-如果是这种情况,那么当发现内存不足的情况时,您应该让您的函数手动释放其内部结构;不这样做是内存泄漏。

EDIT2: 示例:

#include <iostream>
#include <vector>

void DoStuff()
{
    std::vector<int> data;
    //insert a whole crapload of stuff into data here.
    //Assume std::vector::push_back does the actual throwing
    //i.e. data.resize(SOME_LARGE_VALUE_HERE);
}

int main()
{
    try
    {
        DoStuff();
        return 0;
    }
    catch (const std::bad_alloc& ex)
    {   //Observe that the local variable `data` no longer exists here.
        std::cerr << "Oops. Looks like you need to use a 64 bit system (or "
                     "get a bigger hard disk) for that calculation!";
        return -1;
    }
}

EDIT3:
好的,据评论员说,有一些系统在这方面没有遵循标准。另一方面,在这样的系统上,无论如何您都将成为SOL,所以我不明白为什么他们值得讨论。但是,如果您使用的
这样的平台,则应牢记这一点。



 类似资料:
  • 问题内容: 我正在学习CopyOnWriteArrayList类。 复制新阵列的目的是什么? 是其他线程读取数组吗? 因此,如果系统具有高并发性,并且大多数线程的操作都在读取而不是写入,那么最好使用。 问题答案: 如该链接所述: CopyOnWriteArrayList是Java 5并发API中引入的并发Collection类,以及它在Java中流行的表亲。 工具列表界面类似,并且但它的一个线程安

  • 问题内容: 我需要在C中获取当前进程的内存使用情况。有人可以提供在Linux平台上执行此操作的代码示例吗? 我知道获取内存使用情况的方法,但是我不知道如何在C中捕获它。 顺便说一句,它是针对我正在修改的PHP扩展(当然,我是C新手)。如果PHP扩展API中有可用的快捷方式,那将更加有用。 问题答案: 您始终可以像常规文件一样在系统中打开“文件” (使用“自我”符号链接,因此您不必查找自己的pid)

  • 我正在一个项目,需要处理成千上万的活动套接字并发连接。现在我正在查看内存使用和V8引擎,我使用的是Node.js V0.10.19(稳定)

  • 问题内容: 我写了一个程序,可以总结如下: 实际代码(尤其是)要复杂得多。仅使用将其当作参数的这些值(意味着它不引用) 基本上,它将巨大的数据集加载到内存中并进行处理。输出的写操作委托给一个子进程(它实际上写到多个文件中,这需要很多时间)。因此,每次处理一个数据项时,它都会通过res_queue发送到子流程,然后该子流程根据需要将结果写入文件中。 子流程不需要访问,读取或修改以任何方式加载的数据。

  • 我认为它们的分配如下: 全局变量-------->数据 静态变量-------->数据 常量数据类型------>代码 局部变量(在函数中声明和定义)---------->堆栈 在main函数中声明和定义的变量------>堆 指针(例如,、)-------->heap 动态分配的空间(使用malloc和calloc)-------->stack 我只是从C的角度提到这些变量。 如果我不对,请指正

  • 本文向大家介绍C#反射内存的处理分析,包括了C#反射内存的处理分析的使用技巧和注意事项,需要的朋友参考一下 本文实例分析了C#反射内存的处理。分享给大家供大家参考。具体分析如下: 这段时间由于公司的项目的要求,我利用c#的反射的机制做了一个客户端框架。客户端里的所有的模块都是以一定形式进行提供,例如:FORM,UserControl. 在做的过程中很简单与愉快。具体的过程如下: 1. 收集客户的需