“新”算子的不同行为 - 动态记忆分配

时间:2014-08-01 05:05:38

标签: c++ linux memory memory-management

我在嵌入式设备中测试了一个带有简单内存分配程序的示例try-catch块,该嵌入式设备只运行64MB内存,具有自定义的Linux OS 32位Xscale Arm架构。我的目的是验证正常的try catch块是否会当这个设备上没有内存时工作。我列出如下代码。假设这是program1。

#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]”。让我们假设这是program2.I重新编译程序并在同一台设备上执行

计划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,因为我打错了。

1 个答案:

答案 0 :(得分:0)

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

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

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

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

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