PC-98シリーズ/MS-DOS(Ver.6.2)/MS-C
「今時98か!?」って言わないで下さい。仕事なんです・・・。

malloc関数で、メモリ不足を起こしているPGを直さなければならなくなりました。EMSメモリ等拡張メモリが使えれば解決できるんじゃないかなぁと漠然と思ったのですが・・・。何かいい方法はありませんか?(サンプルなど添えていただけるとうれしいのですが)よろしくお願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (5件)

私「愛用」の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メモリを利用するか
ディスクにスワップするか指定出来ますから
全部適用しておけばメモリ不足なんて消え去ります

----

てな感じでどうでしょうか
それではおやすみなさい(←?)
    • good
    • 0
この回答へのお礼

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

お礼日時:2001/06/13 09:30

アッパーメモリの空きが37kですか。


config.sysで登録しているものの中でdevice=と指定されているものをdevicehigh=と書き換えてみるとか、autoexec.batの中で常駐ソフトをloadhighとかしてアッパーメモリに逃がすというアイデアではあまり救えなそうですね。

今更の質問ですみませんが、mallocで取得したいと思うメモリのサイズを教えていただけないでしょうか?mallocがうまくいかないためにEMSを使用するというのは、あまり良いアイデアとは思えないもので...。

一応EMSに関わる説明のページをお知らせしておきますけれど、理解しにくいようなら補足しますので。

参考URL:http://www2.muroran-it.ac.jp/circle/mpc/pc98dos/ …
    • good
    • 0
この回答へのお礼

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

お礼日時:2001/06/13 09:26

基本的にはコンベンショナルメモリしかmallocの対象になりません。


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

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

お礼日時:2001/06/13 09:31

こんにちは、honiyonです。


 HIMEMを使うのも手ですが、基本はやっぱりプログラムスリム化です。

  ○無駄な処理を省く
    汎用的に作ってある関数があり、一定の用途にしか使っていない場合は
   その用途に特化し、処理をスリム化する。
  ○無駄なデータは即破棄
    無駄に mallocして使いもしてないメモリは、使用後即freeする。
  ○無駄に大きい変数を消す
    255まで使いもしないのに intやlongで確保しているものは smallint
   に定義し直す。
  ○無駄な関数呼出は回避する。
    繰り返し使うものでもないのに(多分汎用性を重視して)関数化してあ
   るものを、直接本処理に組み込んでしまう。
  ○いざとなればアセンブラ
    メモリ効率の悪そうな処理を、アセンブラで効率の良い処理を記述する。
   (最近コンパイラ頭良いから逆に非効率になるかも?)

 あと、データをテンポラリファイルを作って、ファイルに吐き出すのも手ですね。 で、必要になったら読み込んで来る。 スワップファイルの要領です。

 とりあえずアドバイスでした。
 参考になれば幸いです(..

 
    • good
    • 0
この回答へのお礼

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

お礼日時:2001/06/13 09:36

とりあえず、PGが動いていない状態のメモリ量はいくつか教えていただけると助かります。



EMSを使う方法、DOSエクステンダに頼る方法など、いくつか思いつきますが、いずれもクセがあり、簡単ではないです。

まず、思ったのが、デバイスドライバの調整でUMB/HMAを駆使してDOSメモリ領域をできるだけ大きく取る努力をしたほうが良いのでは?ということでした。

この回答への補足

難しそうなのですね・・・。
ちなみに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 はハイメモリ領域に常駐しています.

補足日時:2001/06/04 16:44
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qmallocで確保するメモリの領域を限定する方法

mallocで確保するメモリの領域を限定する方法というものは存在するのでしょうか?

例えば、
mallocを使ってメモリを確保するときに、
アドレス:0x00001000から0x00002000の間でメモリを確保してください。

といった感じです。
宜しくお願いいたします。

Aベストアンサー

特定アドレスのメモリを割り付けるのであれば、静的に割り付けるか、それに近い方法を取らざるをえません。
処理系に依存しない方法はありませんので、処理系を補足してください。

いずれにせよ、取りうる方法は限られています。
ひとつは、リンク時にアドレス指定で配列を割り付ける方法であり、もうひとつは(もし使えるのであれば)MMUを自分で制御して、該当アドレスに仮想メモリを配置する方法です。
ハードウェアの設計も自分でできる(能力的にも権限的にも)のであれば、もっと別の方法があるかもしれません。

Qmallocしたメモリの開放

かなり基本的なことですいませんが、
下記のようなイメージのコードで確保したメモリを
確実に開放するにはどうしたらいいでしょうか?

やりたいこととしては、動的に確保したメモリにデータを
入れて、それをベクトルに入れて使いまわしたいです。
下記のコードからfreeの部分をやめても大丈夫でしょうか?その場合、どうやってメモリ開放するんでしょうか?
ベクトルが消滅すればメモリが開放されるんでしょうか?
テストしてみましたが、減った気配がない。。。
根本的に考え方がおかしいかもしれません。。。
お助けください。
お願いします。


wchar_t str[6] = L"あいうえお";
wchar_t* mem = (wchar_t*)malloc(6 * sizeof(wchar_t));
wcsncpy(mem, str, 6);

std::vector<wchar_t*> vetorTemp; //実際グローバル変数
vetorTemp.insert(vetorTemp.end(), mem);

free(mem); // ここで開放するとvetorTempの中身も利用できなくなってしまった

かなり基本的なことですいませんが、
下記のようなイメージのコードで確保したメモリを
確実に開放するにはどうしたらいいでしょうか?

やりたいこととしては、動的に確保したメモリにデータを
入れて、それをベクトルに入れて使いまわしたいです。
下記のコードからfreeの部分をやめても大丈夫でしょうか?その場合、どうやってメモリ開放するんでしょうか?
ベクトルが消滅すればメモリが開放されるんでしょうか?
テストしてみましたが、減った気配がない。。。
根本的に考え方がおかしいかもしれま...続きを読む

Aベストアンサー

> 下記のコードからfreeの部分をやめても大丈夫でしょうか?

何をもって大丈夫とするかによります。簡単な処理を行ってすぐ終わるようなプログラムであれば、現実的には大丈夫かと思います。

> その場合、どうやってメモリ開放するんでしょうか?

プログラムを終了させるしかありません。

> ベクトルが消滅すればメモリが開放されるんでしょうか?

解放されません。

単に、ワイド文字列をベクタで管理したいだけであれば、素直にstd::wstringを使った方がよいかと思います。

Qmalloc、new のメモリ確保について

mallocで確保できる最大メモリ領域と
newで確保できる最大メモリ領域を知りたいです。

ご存知の方、教えて下さい。

Aベストアンサー

> malocで確保出来る最大メモリ領域は決まっていない
> と言うことで宜しいのでしょうか。

決まっていないのではなく、知る方法がないのです。
実装によっては、決まっていない(そのときどきの状況による)場合もあると思います。

> new演算子で、charの配列のメモリ領域を確保しようとする場合
>
> char * buff;
> buff = new char[100000];
>
> も同様に、確保できるメモリ領域は決まっていない
のでしょうか?

この場合、割付けに成功すれば、少なくとも100000バイトを確保できるだけです。実際にどれだけ確保したのか、あるいは同様の割付けをどれだけ行えるかを知る一般的な方法はありません。

Qmalloc メモリリークについて

#include<stdio.h>
#include<stdlib.h>
void alloconly(void)
{
const int sz=10;
static int n=0;
void *p;
p=(void*)malloc(sz);
if(p==NULL){
printf("動的確保不可 %d\n",n+1);
printf("確保メモリサイズ %d byte\n",sz*n);
exit(-1);
}
++n;
}
int main(void)
{
for(;;){
alloconly();
}
}と言うプログラムがある本に載っており、回答として
  動的確保不可 *******(数字)
  確保メモリサイズ *********byte(数字)となっていますが私の環境(Reshat Linux)では
  強制終了します で終了してしまいます。原因が判らず困っています。ご解答願います。

Aベストアンサー

正直、調べていました。私が提示したサンプルはこの場合意味ないみたいです。
「memory overcommit」
というものらしいです。解説は、URLにありますが、
----------------------------------
カーネル2.4の場合に
あまりに大きな確保要求は拒絶するが、そうでない場合には、
現在未使用の物理メモリ(以下ページフレームと呼ぶ)+未使用のswap" と要求のメモリ量を厳密には
見比べずに許可不許可を決めるという手法 
-----------------------------------
少し勉強になりました。
組み込み屋としては、信じられないアルゴリズムです。

参考URL:http://d.hatena.ne.jp/yupo5656/20040624/p1

Qmalloc関数によるメモリの確保

C初心者です。
malloc関数によるメモリの確保に関して教えてください。

2次元配列のサイズに対してmalloc関数の引数値をたとえば、
(double*)malloc(datasize*sizeof(double))
などとしメモリ領域を確保すると、メモリアドレスはデータのサイズ
によらず一定 1234044、1234048となります。
データサイズを大きくし、datasize*sizeof(double)が16Kバイトを超えるとcmd.exeがエラーとなり落ちます。
デバックモードで実行すると
「"System.AccessViolationException"のハンドルされていない例外が不明なモジュールです。で発生しました。

追加情報:保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリがこわれていることが考えられます」
というメッセージがでます。

コンパイラはExpressEdition2008です。
この現象を回避するにはどうすべきか、なぜこのようなことが起こるのかご教授ください。

よろしくお願いいたします。

C初心者です。
malloc関数によるメモリの確保に関して教えてください。

2次元配列のサイズに対してmalloc関数の引数値をたとえば、
(double*)malloc(datasize*sizeof(double))
などとしメモリ領域を確保すると、メモリアドレスはデータのサイズ
によらず一定 1234044、1234048となります。
データサイズを大きくし、datasize*sizeof(double)が16Kバイトを超えるとcmd.exeがエラーとなり落ちます。
デバックモードで実行すると
「"System.AccessViolationException"のハンドルされていない例外が不明...続きを読む

Aベストアンサー

質問の意味が今ひとつ解らないのですが、
for(k=0;k<len1/8;k++){

for(i=0;i<8;i++){

*(in+i+8*k)=data[i];

}

}

の部分で、in配列は
int in[2000];
なのに、
*(in+i+8*k)
のkの最大値は(len1/8-1)です。len1は
int len1=10000;
なので、in配列の後のメモリを破壊してしまいます。


人気Q&Aランキング

おすすめ情報