• ベストアンサー

PC-98で拡張メモリを使えたら・・・。

PC-98シリーズ/MS-DOS(Ver.6.2)/MS-C 「今時98か!?」って言わないで下さい。仕事なんです・・・。 malloc関数で、メモリ不足を起こしているPGを直さなければならなくなりました。EMSメモリ等拡張メモリが使えれば解決できるんじゃないかなぁと漠然と思ったのですが・・・。何かいい方法はありませんか?(サンプルなど添えていただけるとうれしいのですが)よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • verdian
  • ベストアンサー率75% (3/4)
回答No.4

私「愛用」のMS-Cはversion7.0Aですので バージョンが違ってたらお役に立てないかもしれませんが ご了承下さい ---- メモリが足らないとの事ですが 私の思いついた解決方法は2つあります ---- 「1:メモリモデルの変更」 ご存知でしたら読み飛ばして下さい MS-DOS…というよりMS-Cは 6種類のメモリモデルと呼ばれるものがあります 詳しい説明は省かせて頂きますが 簡単に言えば(デフォルトの)データのアドレッシングを 16ビット・32ビットのどちらで行うかという事です 通常は最小サイズのスモールメモリモデルが適用されます この場合(デフォルトの)データの参照は 16ビットですので malloc で利用できるメモリは 64キロバイト以下に制限されます これじゃちっちゃすぎますよね! そこでメモリモデルをより大きいものに変更します ミドルメモリモデル・ヒュージメモリモデルの2つが 候補として考えられますが ここは確実性の為に最大のヒュージメモリモデルにします 方法としては CL コマンドラインオプションに /AH を追加して下さい これでデータの参照は32ビットで利用できますから 利用できるデータサイズはかなり大きくなります 因みにポインタのサイズが変わるので 不具合が発生しない様に注意が必要ですが… また メモリモデルを変更せずにもデフォルトセグメントを 越えてアクセスは可能でして… 動的配置に malloc ではなく _fmalloc や _halloc を利用するのですが 詳しくはマニュアルでお願いします… ---- 「2:拡張メモリ等を使用」 あとはおっしゃる通り拡張メモリ等を使用する方法ですね バージョン7.0Aではサポートされているのですが 実はランタイムライブラリの中に 仮想メモリを扱ってくれるモジュールが有って 関数は _vheapinit _vheapterm _vmalloc _vfree ... といった感じでまだまだ有ります これは仮想メモリ初期化の _vheapinit 関数の引数で 拡張メモリ・EMSメモリを利用するか ディスクにスワップするか指定出来ますから 全部適用しておけばメモリ不足なんて消え去ります ---- てな感じでどうでしょうか それではおやすみなさい(←?)

garigai
質問者

お礼

MS-C Ver.6を使用しておりましたので拡張メモリのサポートは、ありませんでした。今回はハードディスクに逃がす方法をとりました。 いろいろアドバイスをいただきましてありがとうございました。メモリに関しては、じっくり考えていきたいと思っています。わからないことがまた出てきたらよろしくお願いいたします。

その他の回答 (4)

  • YoshiMu
  • ベストアンサー率41% (96/229)
回答No.5

アッパーメモリの空きが37kですか。 config.sysで登録しているものの中でdevice=と指定されているものをdevicehigh=と書き換えてみるとか、autoexec.batの中で常駐ソフトをloadhighとかしてアッパーメモリに逃がすというアイデアではあまり救えなそうですね。 今更の質問ですみませんが、mallocで取得したいと思うメモリのサイズを教えていただけないでしょうか?mallocがうまくいかないためにEMSを使用するというのは、あまり良いアイデアとは思えないもので...。 一応EMSに関わる説明のページをお知らせしておきますけれど、理解しにくいようなら補足しますので。

参考URL:
http://www2.muroran-it.ac.jp/circle/mpc/pc98dos/ems/ems.html
garigai
質問者

お礼

早急な対応だったため、今回はハードディスクに逃がす方法をとりました。 いろいろアドバイスをいただきましてありがとうございました。メモリに関しては、じっくり考えていきたいと思っています。わからないことがまた出てきたらよろしくお願いいたします。

回答No.3

基本的にはコンベンショナルメモリしかmallocの対象になりません。 解決策としては (1)DOSエクステンダによりプロテクトメモリを使用する。  もうどこもサポートしていないでしょうね。 (2)mallocで使用している部分をHDDにとるように書き換える。  プログラムにもよりますが、配列に格納できるようなデータであれば、メモリ取得ルーチンをディスクに対して行えるようなdalloc関数を作成するのも有効です。 (3)プログラムを分割する。  オーバーレイするように設計しなおし、コンベンショナルエリアを空ける。  ただし、分割設計によってはまったく意味がないこともあります。

garigai
質問者

お礼

早急な対応だったため、今回はハードディスクに逃がす方法をとりました。 いろいろアドバイスをいただきましてありがとうございました。メモリに関しては、じっくり考えていきたいと思っています。わからないことがまた出てきたらよろしくお願いいたします。

  • honiyon
  • ベストアンサー率37% (331/872)
回答No.2

こんにちは、honiyonです。  HIMEMを使うのも手ですが、基本はやっぱりプログラムスリム化です。   ○無駄な処理を省く     汎用的に作ってある関数があり、一定の用途にしか使っていない場合は    その用途に特化し、処理をスリム化する。   ○無駄なデータは即破棄     無駄に mallocして使いもしてないメモリは、使用後即freeする。   ○無駄に大きい変数を消す     255まで使いもしないのに intやlongで確保しているものは smallint    に定義し直す。   ○無駄な関数呼出は回避する。     繰り返し使うものでもないのに(多分汎用性を重視して)関数化してあ    るものを、直接本処理に組み込んでしまう。   ○いざとなればアセンブラ     メモリ効率の悪そうな処理を、アセンブラで効率の良い処理を記述する。    (最近コンパイラ頭良いから逆に非効率になるかも?)  あと、データをテンポラリファイルを作って、ファイルに吐き出すのも手ですね。 で、必要になったら読み込んで来る。 スワップファイルの要領です。  とりあえずアドバイスでした。  参考になれば幸いです(..  

garigai
質問者

お礼

確かにおっしゃる通りです。非常に効率の悪い作りをしてあります。 ただ今回は、早急な対応だったためハードディスクに逃がす方法をとりました。 いろいろアドバイスをいただきましてありがとうございました。こいつは、気合を入れてスリムにしていきたいと思っています。

  • YoshiMu
  • ベストアンサー率41% (96/229)
回答No.1

とりあえず、PGが動いていない状態のメモリ量はいくつか教えていただけると助かります。 EMSを使う方法、DOSエクステンダに頼る方法など、いくつか思いつきますが、いずれもクセがあり、簡単ではないです。 まず、思ったのが、デバイスドライバの調整でUMB/HMAを駆使してDOSメモリ領域をできるだけ大きく取る努力をしたほうが良いのでは?ということでした。

garigai
質問者

補足

難しそうなのですね・・・。 ちなみにMS-Cは、Ver.6.0Aを使用しています。 下記は、「MEM」をリダイレクションしたものです。 メモリの種類     合計  = 使用 + 空き ---------------- -------- -------- -------- コンベンショナル 640K 146K 494K アッパー メモリ 78K 41K 37K 予約済み 384K 384K 0K XMS メモリ 14,258K 2,677K 11,581K ---------------- -------- -------- -------- 全メモリ 15,360K 3,248K 12,112K 全 1MB 以下メモリ 718K 187K 531K 全 EMS メモリ 14,272K (14,614,528 バイト) 空き EMS メモリ 11,696K (11,976,704 バイト) 最大実行可能プログラムサイズ 493K (505,312 バイト) 最大空きアッパーメモリブロック 19K (19,344 バイト) MS-DOS はハイメモリ領域に常駐しています.

関連するQ&A

  • メモリのセグメント違反の解決方法を教えてください。

    こんにちわ, 現在プログラムを作成しているのですが,Segmentation Faultが出て困っています。 そのセグメント違反が出ているのがmallocの中(PCインナーの関数)で普通ならmallocの返り値がNULLかそれ以外かということになりますが,それ自体も中でセグメント違反が起こるので帰ってきません。 MALLOC_CHECK_=1によってその触っているポインターを見ると, free(): invalid pointer 0x93c5380! free(): invalid pointer 0x93c5c18! とでるので,おそらくmallocのなかで必要なくなったポインターをフリーをしていると考えられるのですが, gdbのwatchpointでそのアドレスを指定してみてみると,メインに入る前にそのポインタ自体をいじっている関数も内部的な関数みたいでどこをなおすとセグメント違反が直るのかわかりません。 このようなメモリ問題がおきたときどのようなツールや解決法があるのでしょうか。 よろしくお願いします。

  • malloc使用後のメモリアロケーションエラー(MS-C7.0)

    初めて投稿させていただきます。 現在PC:98 OS:MS-DOS 言語:MS-C7.0のhugeモデル という環境で プログラミングを行っております。しかし、config.sys,autoexec.batを 工夫してもメモリ不足を補えず、変数と動的にすることにしました。 c言語のテキストを参考に kansu() { char *p; p=(char *)malloc(256*256*sizeof(char)); if(p=null) printf("メモリ確保に失敗"); ・ ・ free(p); } とすると kansu終了直後に"メモリアロケーションエラー"がでます。 自分ではどこが悪いのわからず、ここでお聞きすることにしました。 上記の中の原因、もしくは原因と考えられることを教えてください。 よろしくおねがいします。

  • 仮想メモリでない環境でのmalloc freeのよいアルゴリズムを教えてください

    ゲーム機の開発をしています。 仮想メモリがないので、mallocとfreeを不定の順序で繰り返しているとヒープ領域が断片化し、そのうちにメモリは不足していないはずなのにmallocできなくなります。ゲーム機のSDKにはそういうことを想定しているのか malloc、free の代替関数を設定できるようになっています。そこで、代替関数を用意しようと考えていると考えています。 完全に断片化をさけるには、mallocした逆順にfreeするとか使い方の工夫をしないと無理とは思いますが、通信系のライブラリにの内部などでmallocしていたりして完全にはこちらの思うとおりにはできません。テクスチャーなどの常駐でなるべく多くのメモリを使いたいので、ヒープ領域はできるだけ小さくすませたいのです。どんなアルゴリズムでも、ある程度の断片化はさけられないと思いますが、malloc、freeのよいアルゴリズムが紹介されているところがありましたら、御教えください。使われ方との相性があると思いますので、複数のアルゴリズムが紹介されていればうれしいです。

  • C/C++言語のメモリについて

    C言語でメモリを2種類?に分けると、スタックとヒープがあります。 ヒープは mallocなどで確保し、freeで解放しますがスタックは解放する必要がありません。 そのスタックは通常、何バイトまで可能なのでしょうか? あと関数外のファイルの先頭に int[1000000];とした場合、このメモリはmallocで確保していませんが、 どこに作られるのでしょうか? 私のパソコンはメモリが2GBでWindows2000ですが、CやC++で最大、何バイトまでメモリが使えますか? また、一番多くメモリを確保できるなら、OSはなんでも構いません。 解釈等も間違っていたらご指摘していただきたいです。

  • メモリ破壊で困っています。

    学生です。 現在、cの課題プログラムを作成していて、メモリ破壊と思われる現象で困っています。具体的には、 mallocである構造体へのポインタの3次元配列を確保したはずのものが(malloc時にNULLは返ってきていない)、その後、関係のない関数を呼んだ瞬間にその配列の値が書き換えられている。もしくはアクセスできなくなるといった状況です。 gdbで調べてみたところメモリを確保してから破壊されるまでにfreeはしていません。「関数を呼んだ瞬間に」値が変わるというのは原因がまったくわかりません。 どなたか心当たりある方、ぜひともアドバイスをよろしくお願いします。

  • Win32APIでのメモリ管理について

    C→malloc関数 C++→new演算子 Win32API→GlobalAlloc関数 とWin32APIでのメモリ管理の方法にはいろいろありますが、どれを使うのが一番実用的なのか、どれが一番効率的なのかが知りたいです。 あとWin32APIにはHeapAllocという関数もあるようですが、上記の3つは使わずにこの関数を使用したほうがよいのでしょうか。

  • malloc関数によるメモリの確保

    C初心者です。 malloc関数によるメモリの確保に関して教えてください。 2次元配列のサイズに対してmalloc関数の引数値をたとえば、 (double*)malloc(datasize*sizeof(double)) などとしメモリ領域を確保すると、メモリアドレスはデータのサイズ によらず一定 1234044、1234048となります。 データサイズを大きくし、datasize*sizeof(double)が16Kバイトを超えるとcmd.exeがエラーとなり落ちます。 デバックモードで実行すると 「"System.AccessViolationException"のハンドルされていない例外が不明なモジュールです。で発生しました。 追加情報:保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリがこわれていることが考えられます」 というメッセージがでます。 コンパイラはExpressEdition2008です。 この現象を回避するにはどうすべきか、なぜこのようなことが起こるのかご教授ください。 よろしくお願いいたします。

  • 自アプリ内のメモリを管理したい

    こんにちは。 現在C/C++でプログラムを組んでいます。 C/C++でメモリを確保、開放するにはmalloc、new、free,deleteを使うわけですがアプリケーションが開始された時点で、ある一定のメモリを確保しておいてそのメモリから分け与えたりデフラグしたりして自分のアプリで使うメモリを管理したいと思っています。 BYTE* g_allMemory;//グローバル変数 g_allMemory = new BYTE[1024]; プログラムを実行した時点でこのようにメモリを確保しておき要所要所で自作関数を利用してメモリを分け与えたりデフラグしたりして使えるようにしたいのです。 しかしデフラグした瞬間に変数のアドレスがずれてしまって使い物になりません。 これを解決したいのですがアドバイスやお勧めのホームページや参考文献などがあったら紹介をお願いします。

  • メモリ確保の謎。

    C言語のメモリの確保の所でふと疑問に思ったのですが、 malloc,calloc,realloc,memset,memcpyなどの関数を使うときって #include <stdio.h> #include <stdlib.h> #include <memory.h> #include <malloc.h> とか書かないといけないと本にはありますが、#include <stdio.h>だけで なんのエラーにもならずに実行できてしまうのはなぜでしょうか? 実際のプログラムにはmallocとreallocしか使ってないのですが、#include <stdio.h>でできてしまいます。 でも教科書には他にも書かなきゃいけないとかいてありますが、なぜ書かなくても実行できてしまうのでしょうか?

  • メモリの掃除屋さんを使っても。。。

     表題ソフト使用の上、積載メモリ320MB。 こまめにメモリクリーンしてやるのに、 「メモリ不足です。アプリケーションを終了してください」度々とか、いきなりフリーズ。。。こう言った現象が、大して減りません。 OS=Win98Seの限界なのでしょうか? 同時起動してるソフトは ・ノートンインターネットセキュリティ ・ノートンアンチウイルス 位で、ここにMS-Office2000を幾つか開 いています。 そして、メモリ不足を引きこしやすいのが、 ホームページビルダー(ver7.0)。これって、 そんなにメモリ喰いソフトでしたっけ?