我在嵌入式设备中使用一个简单的内存分配程序测试了一个示例 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
,因为我打印错了。
最佳答案
printf
和 fflush
例程可能正在尝试分配内存。他们也可能正在锁定或进行一些其他导致死锁的同步。可能需要内存来分配异常对象(尽管希望任何 self 尊重的运行时都能处理这种情况)。
当没有剩余内存时,大多数 C 库调用的行为可能没有很好地指定(也许它们会死锁或进入循环,或者它们可能会留下损坏的东西,以便当您的 'catch' 尝试打印时,它会死锁)。大多数库都没有明确定义的语义来说明它们在内存不足时(或者即使它们需要使用任何内存)的行为方式。
附加调试器或获取回溯以查看您的进程挂起/等待的位置。
或者,您可以使用不太可能在其实现中分配任何内存的 API 调用来检验我的假设:
exit
有助于识别代码的哪一部分退出(传递不同的数字)write
通常是免分配的(但很难传递运行时字符串)。类似于:write(1, "I am here", strlen("I am here"));
(直接写入调用后无需刷新。)
关于c++ - "New"运算符的不同行为 - 动态内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25073181/