c++ - "New"运算符的不同行为 - 动态内存分配

标签 c++ linux memory memory-management

我在嵌入式设备中使用一个简单的内存分配程序测试了一个示例 try-catch block ,该设备仅使用 64MB RAM 和定制的 linux OS 32 位 Xscale Arm 架构运行。我的目的是验证一个正常的 try-catch block 是否会当此设备上没有内存时工作。我列出代码如下。假设这是程序 1。

#include "stdio.h"
#include "stdlib.h"
int main()
{
    int count;
    int *q[409600];
    printf("\nHeap Leak Starting at..");
    system("date");
    fflush(stdout);
    printf("\n, Count is located at ,%p,",&count);
    for(count=0;count<409600;count++)
    {
            printf("\nCount = ,%d,",count);
            int i=2;
            try
            {
                    fflush(stdout);
                    q[count] = new int[409600];
                    printf("New Success.Allocated %ld Bytes at %p.Difference = 0x%x,\n",(i*100000),q[count],(long)(&i) - (long)q[count]);
                    fflush(stdout);
            }
            catch(...)
            {
                            printf("\nException Caught...New Failed..No Memory Available.\n");
                            fflush(stdout);
                            exit(1);
            }
    }
}

程序 1 的输出:

Thu Jul 31 20:38:00 UTC 2014
Heap Leak Starting at..,

Count is located at ,0xbffffc48,

Count = ,0,New Success.Allocated 200000 Bytes at 0x402c0008.Difference = 0x7fbafc3c,

Count = ,1,New Success.Allocated 200000 Bytes at 0x40451008.Difference = 0x7fa1ec3c,

Count = ,2,New Success.Allocated 200000 Bytes at 0x405e2008.Difference = 0x7f88dc3c,

Count = ,3,New Success.Allocated 200000 Bytes at 0x40773008.Difference = 0x7f6fcc3c,

........The count goes on........

Count = ,1954,New Success.Allocated 200000 Bytes at 0xbf854008.Difference = 0x61bc3c,

Count = ,1955,New Success.Allocated 200000 Bytes at 0xbf9e5008.Difference = 0x48ac3c,

Count = ,1956,New Success.Allocated 200000 Bytes at 0xbfb76008.Difference = 0x2f9c3c,

Count = ,1957,
Exception Caught...New Failed..No Memory Available.

现在这是预期的行为。由于没有内存,因此抛出异常。

然后我将“q[count] = new int[409600]”行修改为“q[count] = new int[100000]”。让我们假设这是程序 2。我重新编译程序并在同一设备上执行.

程序 2 的输出:

Thu Jul 31 20:39:43 UTC 2014

Heap Leak Starting at..,

Count is located at ,0xbffffc48,

Count = ,0,New Success.Allocated 200000 Bytes at 0x402c0008.Difference = 0x7fbafc3c,

Count = ,1,New Success.Allocated 200000 Bytes at 0x40322008.Difference = 0x7fb4dc3c,

Count = ,2,New Success.Allocated 200000 Bytes at 0x40384008.Difference = 0x7faebc3c,

Count = ,3,New Success.Allocated 200000 Bytes at 0x403e6008.Difference = 0x7fa89c3c,

............The count goes on.............

Count = ,5215,New Success.Allocated 200000 Bytes at 0x87d00018.Difference = 0x3816fc2c,

Count = ,5216,New Success.Allocated 200000 Bytes at 0x87d61aa0.Difference = 0x3810e1a4,

Count = ,5217,New Success.Allocated 200000 Bytes at 0x87e00018.Difference = 0x3806fc2c,

Count = ,5218,New Success.Allocated 200000 Bytes at 0x87e61aa0.Difference = 0x3800e1a4,

Count = ,5219,New Success.Allocated 200000 Bytes at 0x87f00018.Difference = 0x37f6fc2c,

Count = ,5220,

此时,进程在 New 操作符处被永远挂起。即使我在后台运行进程,我也无法访问终端。

现在我很困惑地注意到 new 的这种不同行为。请注意,在抛出异常的情况下,我分配的大小 (409600) 比进程挂起的情况 (100000) 大。有人可以帮我澄清 New 的这种不同行为吗?请分享您的想法和一些线索,因为我需要这一突破才能调试同一设备中报告的验证错误。

PS:忽略数字200000,因为我打印错了。

最佳答案

printffflush 例程可能正在尝试分配内存。他们也可能正在锁定或进行一些其他导致死锁的同步。可能需要内存来分配异常对象(尽管希望任何 self 尊重的运行时都能处理这种情况)。

当没有剩余内存时,大多数 C 库调用的行为可能没有很好地指定(也许它们会死锁或进入循环,或者它们可能会留下损坏的东西,以便当您的 'catch' 尝试打印时,它会死锁)。大多数库都没有明确定义的语义来说明它们在内存不足时(或者即使它们需要使用任何内存)的行为方式。

附加调试器或获取回溯以查看您的进程挂起/等待的位置。

或者,您可以使用不太可能在其实现中分配任何内存的 API 调用来检验我的假设:

  • exit 有助于识别代码的哪一部分退出(传递不同的数字)
  • write 通常是免分配的(但很难传递运行时字符串)。类似于:write(1, "I am here", strlen("I am here"));(直接写入调用后无需刷新。)

关于c++ - "New"运算符的不同行为 - 动态内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25073181/

相关文章:

c++ - 除了数组之外,glBufferData() 还可以接受哪些容器类型?

c++ - 使用 unordered_set_of 和自定义类型 boost bimap

python - 在 Python 中处理多个网络接口(interface)

c++ - 无法访问存储在多维 vector 中的对象 (C++)

c++ - 如何在 C++ 中运行 .sql 脚本文件?

linux - 为什么 cp 无法复制/proc/stat 文件?

linux - 运行 cron sh 时出错

java - Hibernate:将 Double 作为 Int 保存到数据库

c - 是否所有程序代码都加载到 text\code section\segment 内存中

c++ - 从 C 包装器创建 C++ 对象