Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用C的DOSBOX中没有可用于malloc的内存_C_Dos_Vga - Fatal编程技术网

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

使用C的DOSBOX中没有可用于malloc的内存,c,dos,vga,C,Dos,Vga,我正在编写一个程序,使用BORLAND 3.1在DOSBOX上用C创建一个基本的图像编辑器(如paint)。现在我正在尝试实现一个简单的撤销按钮。为此,我创建了一个双数组来存储10倍的绘图区域(即288*180)。但是,当添加数组初始化行时,我无法为我在程序的其他功能中使用的双缓冲区分配内存 有没有什么方法可以在DOSBOX或其他实现中获得更多内存而不出现这个问题 我像这样编译我的程序: bcc -mh paint.c struct Operation { int x1; in

我正在编写一个程序,使用BORLAND 3.1在DOSBOX上用C创建一个基本的图像编辑器(如paint)。现在我正在尝试实现一个简单的撤销按钮。为此,我创建了一个双数组来存储10倍的绘图区域(即288*180)。但是,当添加数组初始化行时,我无法为我在程序的其他功能中使用的双缓冲区分配内存

有没有什么方法可以在DOSBOX或其他实现中获得更多内存而不出现这个问题

我像这样编译我的程序:

bcc -mh paint.c
struct Operation
{
    int x1;
    int y1;
    int x2;
    int y2;
    int size;
    int extra;
    int color;
    enum OpCode code; // Circle, Rectangle, Line, Fill, whatever...
};
这是我的代码:

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);
    }

与其将撤消缓冲区保留为10个全屏位图的数组,为什么不只保留一个屏幕和随后的10个后续操作?然后,撤销只是恢复屏幕缓冲区,然后应用随后记住的9个操作

那就是

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
其中“操作”是这样的:

bcc -mh paint.c
struct Operation
{
    int x1;
    int y1;
    int x2;
    int y2;
    int size;
    int extra;
    int color;
    enum OpCode code; // Circle, Rectangle, Line, Fill, whatever...
};
然后是一些“撤销”的伪代码

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);
    }
}
void Undo()
{
如果(撤消操作计数>0)
{
undo_ops_count--;//忘记最后一个操作
//恢复屏幕
memcpy(g_screen_buffer,undo,sizeof(undo));
//在最后一个用户操作之前应用最后一个操作
对于(int x=0;x

绘制新内容的每个用户操作都会附加到undo_ops数组中。如果撤消操作的数组空间不足,只需重新绘制一个新的屏幕缓冲区并删除最旧的操作。我把它作为练习留给你。看看这是如何释放更多内存的,我敢打赌你可以记住更多的10个操作,而不会耗尽内存。

与其将撤销缓冲区保留为10个全屏位图的数组,为什么不保留一个屏幕和随后的10个后续操作呢?然后,撤销只是恢复屏幕缓冲区,然后应用随后记住的9个操作

那就是

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
其中“操作”是这样的:

bcc -mh paint.c
struct Operation
{
    int x1;
    int y1;
    int x2;
    int y2;
    int size;
    int extra;
    int color;
    enum OpCode code; // Circle, Rectangle, Line, Fill, whatever...
};
然后是一些“撤销”的伪代码

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);
    }
}
void Undo()
{
如果(撤消操作计数>0)
{
undo_ops_count--;//忘记最后一个操作
//恢复屏幕
memcpy(g_screen_buffer,undo,sizeof(undo));
//在最后一个用户操作之前应用最后一个操作
对于(int x=0;x

绘制新内容的每个用户操作都会附加到undo_ops数组中。如果撤消操作的数组空间不足,只需重新绘制一个新的屏幕缓冲区并删除最旧的操作。我把它作为练习留给你。看看这是如何释放更多内存的,我敢打赌你可以在不耗尽内存的情况下记住10个以上的操作。

如果你想使用640K以上的内存,你要做的是使用DPMI和DOS扩展器(如CWSDMPI)进行编译,并通过它分配内存。DJGPP是GCC的DOS端口,是DOS可用的最现代化的编译器,目前仍在开发中。(编辑:根据Ross Ridge的说法,DJGPP通过标准库调用自动使用扩展内存。)另一个选项是Watcom C和DOS4G/W,这是当时大多数商业软件使用的选项。该选项现在作为OpenWatcom和DOS/32扩展器提供。您还需要配置DOSBOX以使XMS可用;16MB在1995年是一个巨大的数字。

如果你想使用640K以上的内存,你要做的是使用DPMI和DOS扩展器(如CWSDMPI)进行编译,并通过它分配内存。DJGPP是GCC的DOS端口,是DOS可用的最现代化的编译器,目前仍在开发中。(编辑:根据Ross Ridge的说法,DJGPP通过标准库调用自动使用扩展内存。)另一个选项是Watcom C和DOS4G/W,这是当时大多数商业软件使用的选项。该选项现在作为OpenWatcom和DOS/32扩展器提供。您还需要配置DOSBOX以使XMS可用;16Mb在1995年是一个巨大的数字。

注意:他们说。我强烈建议使用一个不太古老的编译器。我能用更新的编译器在DOSBOX中运行程序吗?你能推荐哪个编译器与DOSBOX兼容?我想你使用的是Borland Turbo C?使用支持XMS的DOS扩展器并设置DOSBOX以分配足够的扩展内存。1995年,随着游戏从DOS转向Windows,8MB是标准配置,但4MB仍然很常见。16MB的内存足以运行为DOS编写的任何程序。10*51840+320*200=582400字节的内存仅用于这两个分配。这几乎是MS-DOS程序可用的所有常规内存。因此,内存不足一点也不奇怪。注意:他们说。我强烈建议使用一个不太古老的编译器。我能使用更新的编译器在DOSBOX中运行程序吗?你能推荐哪个编译器与DOSBOX兼容?我想你使用的是Borland Turbo C?使用支持XMS的DOS扩展器并设置DOSBOX以分配足够的扩展内存。1995年,随着游戏从DOS转向Windows,8MB是标准配置,但4MB仍然很常见。16MB的内存足以运行为DOS编写的任何程序。10*51840+320*200=582400字节的内存仅用于这两个分配。这几乎是MS-DOS程序可用的所有常规内存。所以