简体   繁体   English

没有内存可用于C中的DOSBOX中的malloc

[英]No memory available for malloc in DOSBOX with C

I´m working on a program to create a basic image editor (like paint) on DOSBOX with C using BORLAND 3.1. 我正在研究使用BORLAND 3.1在带有C的DOSBOX上创建基本图像编辑器(如绘画)的程序。 Right now I´m trying to implement a simple undo button. 现在,我正在尝试实现一个简单的撤消按钮。 For this I created a double array to store 10 times the drawing area (which is 288*180). 为此,我创建了一个双精度数组来存储10倍于绘图区域(即288 * 180)。 However, when adding the line of the array intialization, I cannot allocate memory for a double buffer I use in other functionalities of the program. 但是,在添加数组初始化的行时,无法为在程序其他功能中使用的双缓冲区分配内存。

Is there any way I can get more memory in DOSBOX or another implementation that doesn´t give me this problem? 有什么办法可以使我在DOSBOX或其他实现中获得更多内存,而不会出现此问题?

I compile my program like this: 我这样编译程序:

bcc -mh paint.c

This is my code: 这是我的代码:

byte huge undo[51840][10];  // This is the array that is giving me problems
void welcome_screen(){
    BITMAP fondo_inicio,normal_ptr_image,boton_inicio,boton_salir;
    MOUSE  mouse_welcome;
    unsigned long int  h;
    int a[2];
    byte *double_buffer;
    sword new_x, new_y;
    word redraw,press,release;
    sword dx,dy=0;
    MOUSEBITMAP *normal_pointer=NULL;
    MOUSEBITMAP *mouse_new=NULL;
    word last_time;

    int i,done = 0;

    filled=-1;

    /* allocate memory for double buffer and background image SCREEN_SIZE = 320*200 */
    if ((double_buffer = (byte *) malloc(SCREEN_SIZE)) == NULL)
    {
        printf("Not enough memory for double buffer.\n"); // ---> This is the error I get when adding the above line
        exit(1);
    }

If you want to use memory above 640K, what you want to do is compile using DPMI, with a DOS extender such as CWSDMPI, and allocate memory through it. 如果要使用640K以上的内存,则要做的是使用DPMI和DOS扩展程序(例如CWSDMPI)进行编译,并通过它进行分配。 DJGPP, the DOS port of GCC, is the most modern compiler available for DOS, and is still being developed. GCC的DOS端口DJGPP是可用于DOS的最现代的编译器,并且仍在开发中。 ( Edit: According to Ross Ridge, DJGPP uses extended memory automatically with the standard library calls.) Another option, which is what most commercial software at the time used, is Watcom C with DOS4G/W. 编辑:根据Ross Ridge的说法,DJGPP通过标准库调用自动使用扩展的内存。)另一种选择是DOS4G / W,它是当时使用的大多数商业软件,是WatcomC。 This is available today as OpenWatcom and the DOS/32 extender. 它现在可以作为OpenWatcom和DOS / 32扩展器使用。 You will also need to configure DOSBOX to make XMS available; 您还需要配置DOSBOX以使XMS可用。 16MiB was a hefty amount back in 1995. 早在1995年,16MiB就是一笔巨款。

Rather than keeping your undo buffer as an array of 10 full screen bitmaps, why not just preserve one screen and the 10 subsequent operations that followed on it? 而不是将撤消缓冲区保留为10个全屏位图的数组,为什么不只保留一个屏幕及其后的10个后续操作? Then an undo is just restoring the screen buffer and then applying the 9 remembered operations that followed. 然后撤消操作只是还原屏幕缓冲区,然后应用随后记住的9个操作。

That is... 那是...

byte undo[288*180]; // one screen of memory representing what the screen looked like 10 operations ago

struct Operation undo_ops[10]; // the last 10 operations since the undo buffer was formed
int undo_ops_count; // number of elements in above array

Where "Operation" is something like this: 其中“操作”是这样的:

struct Operation
{
    int x1;
    int y1;
    int x2;
    int y2;
    int size;
    int extra;
    int color;
    enum OpCode code; // Circle, Rectangle, Line, Fill, whatever...
};

And then some pseudo-code for what an "Undo" actually does 然后是一些有关“撤消”实际操作的伪代码

void Undo()
{
    if (undo_ops_count > 0)
    {
        undo_ops_count--;  // forget the last operation

        // restore the screen
        memcpy(g_screen_buffer, undo, sizeof(undo));

        // apply the last operations before the last user operation
        for (int x = 0; x < undo_ops_count; x++)
        {
            ApplyOperation(g_screen_buffer, &undo_ops[x]); // re-draw what the user did on top of the restored screen buffer
        }
        RepaintScreen(g_screen_buffer);
    }
}

Each user action of drawing something new gets appended to the undo_ops array. 绘制新内容的每个用户操作都会附加到undo_ops数组中。 If you run out of array space for undo_ops, you merely redraw a new screen buffer and drop the oldest operation. 如果undo_ops的阵列空间用完了,您只需重画一个新的屏幕缓冲区并删除最早的操作即可。 I'll leave that as an exercise for you. 我将其留给您练习。 Seeing how this frees up a lot more memory, I'll bet you can remember a lot more than 10 operations without running out of memory. 看到这如何释放更多的内存,我敢打赌,您可以记住10多个操作,而不会耗尽内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM