为什么我的程序在执行到 for 循环时崩溃了?

问题描述 投票:0回答:2

我有一个问题

memset
和Turbo C中的一个大for循环

当代码开始崩溃时,我正在 Virtual Box 上的 MS-DOS 6.22 上使用 Turbo C++ 3.00 编写基于模式 13h 的小型图形库。

我知道 Turbo C 确实过时了,但我想在类似 DOS 的系统上尝试旧式编码。

这是我的代码:

#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <dos.h>

int main();

int main(){
  int *buf;
  unsigned int i;

  _AH = 0x0;
  _AL = 0x13;
  geninterrupt(0x10);

  buf = malloc(sizeof(int)*64000);
  memset(buf,15,64000); //can't figure out why memset does not work properly...

  for (i=0;i< (unsigned int)64000;i++){
    buf[i] = 15; //trying to forcely set each byte to 0xf...
    pokeb(0xA000,i,buf[i]); //outputting to VGA

  }
  getch();
  free(buf);
  return(0);

}


我想做的基本上是用白色填充屏幕。

一旦我开始编码,我注意到

memset
没有将堆数组的所有字节设置为 0xf。

所以我决定通过编写 for 循环来手动设置它们。

我运行它,它像黄油一样工作。刚把字节戳到屏幕上,程序就崩溃了,想不通为什么……

有什么帮助吗?

PS:我对C很陌生

c x86-16 dos turbo-c
2个回答
2
投票

在 MS-DOS 中,内存以

segments
的形式组织,不超过 64K。

你的 64,000 个整数缓冲区比那个大。

如果您使用

unsigned char
(单字节)而不是
int
unsigned int
(我似乎记得在 DOS/Turbo C++ 中是 16 位),那么它将适合单个“段”并且应该可以正常工作。

...当您将字节存储到视频内存中时,您不需要整数为您提供的额外位宽。

#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <dos.h>

int main() {
  unsigned char *buf;
  unsigned int i;

  _AH = 0x0;
  _AL = 0x13;
  geninterrupt(0x10);

  buf = malloc(64000);
  memset(buf, 15, 64000);

  for (i=0; i < (unsigned int)64000; i++) {
    pokeb(0xA000, i, buf[i]); //outputting to VGA
  }
  getch();
  free(buf);
  return(0);
}

0
投票

您已经告诉

memset
将前 64000 个字节填充为 15。但是,
buf
的大小不是 64000,而是
sizeof(int)*64000
。所以,你可能认为解决方案是

memset(buf, 15, sizeof(int)*64000);

但是,这会将每个 byte 设置为 15,而您希望将每个 integer 设置为 15。也就是说,假设

int
是四字节宽并且您有一个大端架构,您希望内存布局为是

00 00 00 0f 00 00 00 0f 00 00 00 0f ...

据我所知,除了

之外,没有其他简单的方法可以做到这一点
for (i=0; i<64000; i++) {
    buf[i] = 0xf;
}

然而,你真的根本不需要使用

int
。相反,试试

unsigned char *buf;

buf = malloc(64000);
if ( !buf ) {
    // handle the error
}
memset(buf, 15, 64000);
© www.soinside.com 2019 - 2024. All rights reserved.