有个程序,需要处理一张16384x16384大小的图片,需要把整个图片读入内存,常规处理了半天总是内存报错,起初怀疑GDI的问题,后来发现是内存申请问题。很奇怪,32位程序也应该有2G的用户内存啊,怎么new不出来1G内存?

无聊,写了个测试内存申请程序如下:

int M = 1024*1024;
char* p;
for(int i=0; i<INT_MAX; ++i){
    try{
        p = new char[i * M];
        if(p){
            delete []p;
        }
        catch(...){
            print("bad alloc", i);
            break;
        }
    }
}
本人一直使用,c++buider 2010,测试工程是vcl界面工程,发现最大可申请内存是691M,又测试了其他内存管理函数SysAllocMem、GlobalAlloc,发现申请的内存都超不过700M。后来和c++一些群里面的人讨论,有个观点是,可能程序调用的模块,占用了地址,导致没有那么长的连续内存。

上面的代码我又用gcc测试了一下,代码如下:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int M = 1024 * 1024;
    char *p;

    for(int i=0; i<2048; ++i){
        try{
            p = new char[i * M];
            delete []p;
        }
        catch(...){
            printf("bad alloc %i\n", i);
            break;
        }
    }

    system("pause");

}

结果发现,gcc编译的程序,可以申请1G以上内存,那vcl界面工程申请不出来的原因是什么呢?后来想到,如果是程序的一些模块占用的地址空间,导致没有连续内存的话,那么整理一下模块会不会好点?c++builder有个静态编译模式(不依赖链接库和bpk库),于是修改工程属性,测试了一下,果然。虽然结果记得1300多,没有纯dos程序多,但够了。

 

于是这个大图片就能顺利显示出来了,配合自己写的缩放程序,自我感觉很良好: