メモリアローケーションエラー

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
polpol

メモリアローケーションエラー

#1

投稿記事 by polpol » 14年前

以下のサンプルを実行するとメモリアローケーションエラーです。COMMANDがロードできません
リセットしてくださいというエラーが出ます。

コード:

 
#include "window.c"  /* ラージモデルでコンパイル */

/* シダ(fern)のデータ */
double left = -5, bottom = 0, right = 5, top = 10,
	   a[] = {  0   ,  0.85,  0.2 , -0.15 },
	   b[] = {  0   ,  0.04, -0.26,  0.28 },
	   c[] = {  0   , -0.04,  0.23,  0.26 },
	   d[] = {  0.16,  0.85,  0.22,  0.24 },
	   e[] = {  0   ,  0   ,  0   ,  0    },
	   f[] = {  0   ,  1.6 ,  1.6 ,  0.44 };

#define N (sizeof a / sizeof a[0])
#define M (25 * N)

int main()
{
	int i, j, k, r, ip[N], table[M];
	double x, y, s, t, p[N];

	/* 確率の計算 */
	s = 0;
	for (i = 0; i < N; i++) {
		p[i] = fabs(a[i] * d[i] - b[i] * c[i]);
		s += p[i];  ip[i] = i;
	}
	/* 整列 */
	for (i = 0; i < N - 1; i++) {
		k = i;
		for (j = i + 1; j < N; j++)
			if (p[j] < p[k]) k = j;
		t = p[i];  p[i] = p[k];  p[k] = t;
		r = ip[i];  ip[i] = ip[k];  ip[k] = r;
	}
	/* 表作成 */
	r = M;
	for (i = 0; i < N; i++) {
		k = (int)(r * p[i] / s + 0.5);  s -= p[i];
		do {  table[--r] = ip[i];  } while (--k > 0);
	}
	/* IFSのアトラクタをプロット */
	gr_on();  gr_window(left, bottom, right, top, 1, 0);
	x = y = 0;
	for (i = 0; i < 30000; i++) {
		j = table[rand() / (RAND_MAX / M + 1)];
		t = a[j] * x + b[j] * y + e[j];
		y = c[j] * x + d[j] * y + f[j];
		x = t;
		if (i >= 10) gr_wdot(x, y, WHITE);
	}
	hitanykey();
	return EXIT_SUCCESS;
}

#if 0  /***************************************************/

/* Sierpinskiの三角形のデータ */
double left = 0, bottom = 0, right = 1, top = 1,
	   a[] = { 0.5 , 0.5 , 0.5  },
	   b[] = { 0   , 0   , 0    },
	   c[] = { 0   , 0   , 0    },
	   d[] = { 0.5 , 0.5 , 0.5  },
	   e[] = { 0   , 1   , 0.5  },
	   f[] = { 0   , 0   , 0.5  };

/* 木のデータ */
double left = -1, bottom = 0, right = 1, top = 1,
	   a[] = {  0   ,  0.1 ,  0.42,  0.42 },
	   b[] = {  0   ,  0   , -0.42,  0.42 },
	   c[] = {  0   ,  0   ,  0.42, -0.42 },
	   d[] = {  0.5 ,  0.1 ,  0.42,  0.42 },
	   e[] = {  0   ,  0   ,  0   ,  0    },
	   f[] = {  0   ,  0.2 ,  0.2 ,  0.2  };

/* もっと現実的な木のデータ */
double left = -1, bottom = 0, right = 1, top = 2,
	   a[] = {  0.05,  0.05,  0.46,  0.47,  0.43,  0.42 },
	   b[] = {  0   ,  0   , -0.32, -0.15,  0.28,  0.26 },
	   c[] = {  0   ,  0   ,  0.39,  0.17, -0.25, -0.35 },
	   d[] = {  0.6 , -0.5 ,  0.38,  0.42,  0.45,  0.31 },
	   e[] = {  0   ,  0   ,  0   ,  0   ,  0   ,  0    },
	   f[] = {  0   ,  1   ,  0.6 ,  1.1 ,  1   ,  0.7  };

#endif
コンパイラはLSI C-86です
ご教授願います。

polpol

Re: メモリアローケーションエラー

#2

投稿記事 by polpol » 14年前

あ、includeファイルの中身忘れてました↓

コード:

 
/***********************************************************
	window.c -- グラフィックス
***********************************************************/
/* 座標変換 */

#include <math.h>
#include "line.c"

static double
	gr_xfac = 1, gr_yfac = 1, gr_xconst = 0, gr_yconst = 0;
#define gr_xscr(x) (int)(gr_xfac * (x) + gr_xconst)
#define gr_yscr(y) (int)(gr_yfac * (y) + gr_yconst)

void gr_wdot(double x, double y, int color)
	/* gr_window() で定めた座標で点 (x, y) に
	   色 color (= 0..maxcolor) をつける */
{
	gr_dot((unsigned int)(gr_xscr(x)),
	       (unsigned int)(gr_yscr(y)), color);
}

void gr_wline(double x1, double y1,
              double x2, double y2, int color)
	/* gr_window() で定めた座標で点 (x1, y1), (x2, y2)
	   を結ぶ線分を色 color (= 0..maxcolor) で描く */
{
	gr_line(gr_xscr(x1), gr_yscr(y1),
	        gr_xscr(x2), gr_yscr(y2), color);
}

void gr_window(double left,  double bottom,
               double right, double top,
               int samescale, int bordercolor)
	/* 窓の左・下・右・上端の座標を指定する.
	   samescale ≠ 0 なら上下と左右の尺度を同じにする.
	   bordercolor ≠ 0 ならその色で枠を描く */
{
	gr_xfac = (XMAX - 1) / (right - left);
	gr_yfac = (YMAX - 1) / (bottom - top);
	if (samescale) {
		if (fabs(gr_xfac) > fabs(gr_yfac))
			  gr_xfac *= fabs(gr_yfac / gr_xfac);
		else  gr_yfac *= fabs(gr_xfac / gr_yfac);
	}
	gr_xconst = 0.5 - gr_xfac * left;
	gr_yconst = 0.5 - gr_yfac * top;
	if (bordercolor) {
		gr_wline(left , bottom, left , top   , bordercolor);
		gr_wline(left , top   , right, top   , bordercolor);
		gr_wline(right, top   , right, bottom, bordercolor);
		gr_wline(right, bottom, left , bottom, bordercolor);
	}
}

コード:

 
/***********************************************************
	line.c -- グラフィックス
***********************************************************/

#include "gr98.c"  /* または "grega.c".  ラージモデルでコンパイル */

void gr_line(int x1, int y1, int x2, int y2, int color)  /* 線分を描く */
{
	int dx, dy, s, step;

	dx = abs(x2 - x1);  dy = abs(y2 - y1);
	if (dx > dy) {
		if (x1 > x2) {
			step = (y1 > y2) ? 1 : -1;
			s = x1;  x1 = x2;  x2 = s;  y1 = y2;
		} else step = (y1 < y2) ? 1: -1;
		gr_dot(x1, y1, color);
		s = dx >> 1;
		while (++x1 <= x2) {
			if ((s -= dy) < 0) {
				s += dx;  y1 += step;
			};
			gr_dot(x1, y1, color);
		}
	} else {
		if (y1 > y2) {
			step = (x1 > x2) ? 1 : -1;
			s = y1;  y1 = y2;  y2 = s;  x1 = x2;
		} else step = (x1 < x2) ? 1 : -1;
		gr_dot(x1, y1, color);
		s = dy >> 1;
		while (++y1 <= y2) {
			if ((s -= dx) < 0) {
				s += dy;  x1 += step;
			}
			gr_dot(x1, y1, color);
		}
	}
}

#if 0  /* テスト用 */

int main()
{
	int i;

	gr_on();
	for (i = 0; i < 100; i++)
		gr_line(rand() % XMAX, rand() % YMAX,
		        rand() % XMAX, rand() % YMAX,
		        rand() % WHITE + 1);
	hitanykey();
	return EXIT_SUCCESS;
}

#endif

コード:

 
/***********************************************************
	gr98.c -- グラフィックス
************************************************************
	グラフィックス基本ルーチン (PC-9801)
	ラージモデル, コンパクトモデル, ヒュージモデルなど,
	データ用ポインタの幅が32ビットのモードでコンパイル
	してください.
***********************************************************/

#ifndef GR98_C
#define GR98_C

#include <stdio.h>   /* fputc, fputs, stderr */
#include <stdlib.h>  /* exit, atexit */
#include <string.h>  /* memset */
#include <dos.h>     /* union REGS, int86 */

#define XMAX  640U  /* 横ドット数 */
#define YMAX  400U  /* 縦ドット数 */
enum {BLACK, BLUE, RED, MAGENTA, GREEN, CYAN, YELLOW, WHITE};  /* 色コード */

#define PLANE1 ((unsigned char *)0xa8000000L) /* 青プレーン */
#define PLANE2 ((unsigned char *)0xb0000000L) /* 赤プレーン */
#define PLANE3 ((unsigned char *)0xb8000000L) /* 緑プレーン */

static union REGS regs;  /* 8086レジスタ */

static int dgetc(void)  /* ctrl-C で止まらない1文字入力 */
{                       /* キーが押されていなければ0を返す */
	regs.h.ah = 6;  regs.h.dl = 0xff;
	int86(0x21, &regs, &regs);  /* DOS call */
	return regs.h.al;
}

void hitanykey(void)  /* キーを押すまで待つ */
{
	fputc('\a', stderr);    /* beep */
	while (dgetc() != 0) ;  /* flush key buffer */
	while (dgetc() == 0) ;  /* wait for any key */
}

void gr_dot(unsigned int x, unsigned int y,
            unsigned int color)  /* 点を表示 */
{
	unsigned int i;
	unsigned char m1, m2;
	static unsigned char
		count = 100,
		mask1[] = { 128, 64, 32, 16,  8,  4,  2,  1 },
		mask2[] = { 127,191,223,239,247,251,253,254 };

	if (--count == 0) {
		if (dgetc() == 0x1b) exit(EXIT_SUCCESS);  /* ESC */
		count = 100;
	}
	if (x >= XMAX || y >= YMAX) return;
	i = 80 * y + (x >> 3);
	m1 = mask1[x & 7];  m2 = mask2[x & 7];
	if (color & 1) PLANE1[i] |= m1;  else PLANE1[i] &= m2;
	if (color & 2) PLANE2[i] |= m1;  else PLANE2[i] &= m2;
	if (color & 4) PLANE3[i] |= m1;  else PLANE3[i] &= m2;
}

void gr_off(void)  /* グラフィック画面表示停止 */
{
	regs.h.ah = 0x41;
	int86(0x18, &regs, &regs);  /* PC-9801 BIOS */
	fputs("\x1b[>5l", stderr);  /* カーソル表示 */
}

void gr_on(void)  /* グラフィック画面初期化・表示開始 */
{
	static int first = 1;

	if (first) {  atexit(gr_off);  first = 0;  }
	memset(PLANE1, 0, 32000);  /* グラフィック画面クリア */
	memset(PLANE2, 0, 32000);
	memset(PLANE3, 0, 32000);
	/* 画面クリア, カーソル非表示, 最下行ユーザ使用 */
	fputs("\x1b[2J\x1b[>5h\x1b[>1h", stderr);
	regs.h.ah = 0x42;  /* スクリーンモード設定 */
	regs.h.ch = 0xc0;  /* 640×400 カラーモード */
	int86(0x18, &regs, &regs);  /* PC-9801 BIOS */
	regs.h.ah = 0x40;  /* グラフィック画面表示開始 */
	int86(0x18, &regs, &regs);  /* PC-9801 BIOS */
}

#endif  /* GR98_C */

#if 0  /* テスト */
int main()
{
	int i, j, k, c;

	gr_on();  k = 0;
	for (c = BLACK; c < WHITE; c++) {
		for (i = 0; i < 40; i++)
			for (j = 0; j < 40; j++) gr_dot(k + i, k + j, c);
		k += 20;
	}
	for (c = WHITE; c >= BLACK; c--) {
		for (i = 0; i < 40; i++)
			for (j = 0; j < 40; j++) gr_dot(k + i, k + j, c);
		k += 20;
	}
	hitanykey();
	return EXIT_SUCCESS;
}
#endif /* テスト */

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: メモリアローケーションエラー

#3

投稿記事 by softya(ソフト屋) » 14年前

お使いのOSは、98/Me/2000/XP/Vista/7のいずれでしょう?
LSI-Cは古いので新しいOSほど支障が出ます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

polpol

Re: メモリアローケーションエラー

#4

投稿記事 by polpol » 14年前

>softyaさん
OSはXPになります。
ググッて調べた結果int86などは、16ビットのコンパイラーでないとできならしいですが・・・

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: メモリアローケーションエラー

#5

投稿記事 by softya(ソフト屋) » 14年前

当方だとフリーの試食版なのでラージモードでコンパイル出来ないので確認不能です。
どちらにしろWin7以降はLSI-C86は使えないので、今後も使うつもりだと厳しいと思いますが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

polpol

Re: メモリアローケーションエラー

#6

投稿記事 by polpol » 14年前

>softoyaさん
僕も試食版でラージモードというのができませんでした(有償版ならできるのでしょうか)
MS-DOSのコンパイラを使うとできるみたいなんですが
色々と面倒なのでint86関数を使わないようにコードいじってみます。
とりあえず解決にしておきます。
ありがとうございました。

アバター
toyo
記事: 35
登録日時: 14年前
住所: 宮崎県

Re: メモリアローケーションエラー

#7

投稿記事 by toyo » 14年前

これはPC-9801という昔のNECパソコン用のプログラムですね
VRAMに画像データを直接書き込んでいるので今のパソコンでは動かないですよ

閉鎖

“C言語何でも質問掲示板” へ戻る