トップページgamedev
986コメント314KB

ゲームプログラミング相談室

■ このスレッドは過去ログ倉庫に格納されています
0001プチ9627m01/11/06 18:47ID:G6Fk/ND/
ゲームプログラミング全般についての質問スレッド。
駄スレ立てる前にココで聞きましょう。

■旧スレ(プログラミング技術板より)
○パート1
http://piza.2ch.net/tech/kako/969/969984472.html
○パート2
http://pc.2ch.net/test/read.cgi/tech/985540361
○パート3
http://pc.2ch.net/test/read.cgi/tech/1002894129/
0778名前は開発中のものです。02/10/26 02:48ID:???
>>777
プロセス終了時のメモリ解放は
OSの管轄ですが何か?

メモリリークが問題になるのは
長時間常駐するプロセスだけ
0779名前は開発中のものです。02/10/26 02:55ID:???
不正な処理で終了した場合も開放してくれる?
0780名前は開発中のものです。02/10/26 03:54ID:???
>>779
まさか、しないと思ってるのか?
0781名前は開発中のものです。02/10/26 04:37ID:???
Win95のころはひどかったな。
一応OSが開放してくれるハズだが、
それを過度に期待したプログラムを組むのは避けた方が無難。
0782名前は開発中のものです。02/10/26 04:44ID:???
関係ないけど、windowsでプログラム書くんだったら
確保したメモリは必ず自分で解放しなくちゃダメだよ。
OSを信用する方が悪い。
0783名前は開発中のものです。02/10/26 07:46ID:???
OSが開放してくれるとしても、それはあくまでも開放ミスに対する
救済措置と思ったほうがいい。確保したメモリは必ず開放するのが鉄則。
0784名前は開発中のものです。02/10/26 10:14ID:???
またmalloc&freeネタか・・・飽きないねえ
0785名前は開発中のものです。02/10/26 12:43ID:???
>>783
> OSが開放してくれるとしても、それはあくまでも開放ミスに対する
> 救済措置と思ったほうがいい
そりゃ違うだろ。

そもそも仮想記憶を使ってる OS の場合、ページテーブルやら TLB (*1) やら
は OS 以外は触れない。そこにバグがあると疑い始めたら、もはやアプリケー
ション側でとれる対策は何もないよ。

(*1)
IA-32 だと TLB はソフトウェアからいじる必要はない(ページテーブルをハード
が勝手にコピーしてくれる)けど、MIPS などは TLB ミスが起きると例外を発生
して、OS が自前で埋める必要がある。
0786名前は開発中のものです。02/10/26 14:26ID:???
どんな環境でも開放しなかったメモリの後始末をしてくれる
という保証は無いからメモリリークするようなプログラムは
そもそも欠陥品と見ていい。だから開放しないと駄目。
それにOSが開放しなかったからといって、それはOSの
過失ではない。プログラム作った奴が悪い。
0787名前は開発中のものです。02/10/26 14:35ID:???
786でまとまりました。

では次の話題。
0788名前は開発中のものです。02/10/26 15:24ID:???
実験に使いたいのですがOSがリソースを開放できない終了方法を教えてください
いくらやってもけしからんことに勝手に開放されてしまいます
0789名前は開発中のものです。02/10/26 16:18ID:???
>>788
Win98でRPCだか何だかを使うと起こりやすいそうだ
使ったことないけど
0790名前は開発中のものです。02/10/26 16:22ID:???
>>788
DOS環境とかゲーム専用機等ならたぶん開放しないのでは。
0791名前は開発中のものです。02/10/26 22:41ID:???
>>745
アルゴリズムが公開されている暗号もある。

>>755
タスクと再帰処理がなぜ両立できないのか分からん。

>>788
何の実験に使うのか知らんが。
ファイルや共有メモリ等、OSが勝手に解放することがないリソースは存在する。
存分に使え。
0792名前は開発中のものです。02/10/27 01:11ID:???
>>786
そもそも「どんな環境でも」なんて言い出したら、それこそ malloc/free がない
世界とか、あっても C 言語の規格書に従ってない環境まで出てくるから、議論
にならんよ。

規格書を行間まで読めば、C 言語の hosted environment を前提とする限り
malloc したメモリは OS に解放されるはず、が結論。

だいたいヒープの仕組みとか仮想記憶の仕組みを知っていれば、そんなに
ビクビクする必要はないと思うんだが。解放されないって、実際にどんな環境
を想定してるんだ?

(スタイルとして解放する方が良いかは別問題な)
0793名前は開発中のものです。02/10/27 01:28ID:???
つーか、解放しないと再利用できないじゃん?
こまめに解放してメモリを開けたほうがいいと思うんだが。
0794名前は開発中のものです。02/10/27 01:52ID:xQ8SKzdu
PS2のアルファブレンド設定を
DirectXでもやりたいのですが、 そういうことはできないのでしょうか?
たしか こんな計算式
 C = (A+B)>>7+D

   A: と B:
   ソースのカラーか フレームバッファのカラー
   
   D: ソースかフレームのアルファ値


0795名前は開発中のものです。02/10/27 03:45ID:???
>>794
IDirect3DDevice8::SetTextureStageState( )
0796名前は開発中のものです。02/10/27 05:52ID:???
>>793
ところが大抵の処理系では
freeは解放済みフラグが立つだけで
実際に解放されるのはプロセス終了時なんだな・・・
0797名前は開発中のものです。02/10/27 06:27ID:???
JAVAなんかはガベッジコレクションを行ってくれるけどね。
0798名前は開発中のものです。02/10/27 09:49ID:???
>>796
それじゃfree自体存在意義ねーじゃん
0799名前は開発中のものです。02/10/27 10:25ID:???
>>798
けど同じプロセスが再び○allocするときは
その解放済みの領域からメモリ確保するので
あながち無意味とも言えない
0800名前は開発中のものです。02/10/27 10:53ID:???
>>798
一種のキャッシュだよ。まっとーなメモリ保護のある環境下で OS を呼び出して
メモリを割り当ててもらうのは

  ソフトウェア割り込みによる特権モード変更
  割り込みハンドラでのレジスタの待避などの定型処理
  (ここで OS のメモリ割り当て関係のコードに入って)
  各種制限のチェック(たとえばユーザあたりのメモリ割り当て越えてないか、
  とか)
  仮想記憶のページテーブル、TLB の変更
  OS の持つ仮想記憶レイヤーにおけるページエントリの変更

と、いろいろ手間がかかる。ユーザ空間で完結できれば、それに越したことはな
い。

このあたりは使ってるライブラリによっても変わってくるけど、昔の UNIX だと
一度 malloc したら二度と OS には返さないのが一般的で、最近でも条件 (*1)
が揃わない限りはまず返さない。

本当に OS からメモリを短時間・大量に借りたいなら malloc/free なんか使っ
ちゃダメです。mmap() とか VirtualAlloc() とか使いましょう。

(*1)
ヒープの端っこが free() されるとか、ページ単位で連続した空間が free される
とか。この条件を緩くして OS 側に返すチャンスを増やそうとすればするほど、
malloc/free が内部で管理・チェックするデータが増え、割り当て・解放に掛か
る時間もメモリ消費も大きくなるというトレードオフがある。

たとえば Solaris だと libc, libmalloc, libmapalloc あたりに実装が異なる
malloc/free がいくつかあるから、ソースを眺めながら処理速度を比べてみると
勉強になるよ。
0801名前は開発中のものです。02/10/27 11:02ID:???
検索で調べてみたが、実際メモリリークは問題になって
るからメモリ開放しないプログラムを書くのは良くないと思う。
0802名前は開発中のものです。02/10/27 17:34ID:PvYfeL9I
>>800
Win32の場合、mallocもVirtualAlloc呼び出してんじゃないの?
同様に、freeはVirtualFreeって感じで。
メモリマップはこれらとは違うだろうけど。
思い切り勘違いなら、ごめんな。
0803名前は開発中のものです。02/10/27 17:36ID:???
>Win32の場合、mallocもVirtualAlloc呼び出してんじゃないの?
Win32じゃなくてCのランタイムライブラリの実装次第

>思い切り勘違いなら、ごめんな。
あやまるくらいなら最初からいい加減なことは書くな
0804名前は開発中のものです。02/10/27 17:49ID:???
>>802
malloc() したら毎回 VirutalAlloc(), free() したら毎回 VirtualFree() してると
思ってる? んなこたないって。ソース読めば明白なんだが、msvcrt.dll だと

1. VirutalAlloc() 系ではなく一つ抽象度が高いHeapAlloc() 系を使っていて、
 こいつがユーザ空間でいろいろメンテナンスしていてる。
2. それに加え C Runtime Library 内部でも、小規模なメモリ割り当てに関して
 毎回 HeapAlloc(), HeapFree() を呼ばないで良いようにキャッシュしている。

と、OS 直のメモリインターフェースから 2 枚の皮をかぶせてある。
0805名前は開発中のものです。02/10/27 17:57ID:???
あと OS が提供するメモリ割り当てのインターフェースは、基本的にページ単位
でしかメモリを割り当ててくれない。VM とか CPU アーキテクチャによるんだが、
たいてい 1 ページは 8192 バイト前後。

だから小さなメモリブロックを割り当てるときに毎回 OS を呼んでるとムダに
なるメモリも莫大になるんで、

 でっかいメモリブロックを OS からもらってきて
 そいつを小さく切り刻んだ上で malloc 呼び出してきた側に返す

っつー仕組みにしてる面もある。

(あと昔の OS だと、そもそもメモリブロックを割り当てるような API を提供
してなかったりな。brk() とか sbrk() で検索してみ)
0806名前は開発中のものです。02/10/27 18:15ID:???
メ モ リ リ ー ク が イ ヤ な ら
 J a v a で も つ か っ て い ろ 
0807名前は開発中のものです。02/10/27 19:01ID:???
>>804
2. はたしか廃止されたような気がする
今手元にないのでわからんが、どっかで見た
0808名前は開発中のものです。02/10/27 23:24ID:???
802だけどよ

malloc=VirtualAlloc呼び出しで解決されてるんじゃないか、
と思ったんで、質問の意味もあって書いてみたんだが。

それをいい加減とか決め付けてる>>803氏んどくように。

あと、HeapAllocは既に廃止されてるはず(MSDN libに載ってたと思う)
今のWin32では、HeapAllocは内部でVirtualAllocを呼び出してるんじゃなかったかな。
0809名前は開発中のものです。02/10/27 23:34ID:???
いろんなmallocの実装を紹介するスレはここですか?
0810名前は開発中のものです。02/10/27 23:47ID:???
>>808
HeapAlloc が内部で VirtualAlloc を呼び出してるのは確かだが、単なる
ラッパじゃない。内部で色々処理をしてる。

それと廃止されたのは GlobalAlloc(), LocalAlloc() だろうが。嘘八百を
並べるなよ……。
0811名前は開発中のものです。02/10/28 01:58ID:???
>>810
訂正さんくす。

HeapAllocが廃止されたってのは、勘違いだったよ。
廃止されたのはGlobalAlloc/Freeで、HeapAlloc/FreeはVirtualAllocで
確保したメモリをヒープ構造で管理してるってことなのね。
Win32APIで開発する時は、たいていHeapAllocと同じことを自前でしてるせいで、
よく知りませんですた。

ご指摘さんくす、と同時に、嘘八百とか書くなよ、ぼけ。
0812名前は開発中のものです。02/10/28 02:03ID:???
それじゃ今後は同様の事態を表現するときは嘘七百五十くらいで。
0813名前は開発中のものです。02/10/28 03:11ID:???
>>811
> HeapAlloc/FreeはVirtualAllocで
> 確保したメモリをヒープ構造で管理してるってことなのね。
全然違うぞ…。なんでそこでヒープ構造が出てくる?
0814名前は開発中のものです。02/10/28 09:40ID:???
>>802,808,811
いいかげん。うそはっぱく。よくしらないのにしったかぶり。
晒しsage
0815名前は開発中のものです。02/10/28 11:02ID:???
>>806
JavaやC#がメモリリークないと思ってるヤツ発見
http://www-6.ibm.com/jp/developerworks/java/010824/j_j-leaks.html
0816名前は開発中のものです。02/10/28 11:57ID:???
うーん、微妙に話題ズレてない?
>799も言うとおり、解放済みマークのついた領域は再利用される。
(そのためのfreeだろ?)
だから、mallocにラッパーが掛かってようが掛かってまいが、
>793が原則として正しいということでいいんでないの?
0817名前は開発中のものです。02/10/28 12:05ID:???
確保したら必ず開放しなくてはいけないと思ってたほうが無難だよ。
そのほうが余計なトラブルの心配しなくて済むじゃん。
0818名前は開発中のものです。02/10/28 20:30ID:???
>>817
俺は

free(p);
free(p);

とかやって、メモリ領域壊したことがある。実際にはこんな簡単なコードじゃ
なくて、サイクルのある複雑なデータ構造で、遠く離れた関数で実行されて
たんだが。

結局、そのデータ構造扱う部分は「でっかくメモリを取って中で使い回し、
使い終わったら丸ごと free する」っつー方針で書き換えました。
0819名前は開発中のものです。02/10/28 20:38ID:???
普通、

free(p);
p=NULL;

ってしない?
0820名前は開発中のものです。02/10/28 20:49ID:???
>>819
しない。そもそも p に相当するものが関数の引数として渡ってくる場合には、
それって無理だし。

free_something(void* p)
{
  free(p);
  p = NULL;
}

func()
{
 free_something(p);
 // p は相変わらず NULL じゃない
}

これは極端な例だけど。あとサイクルがあるデータ構造だと、解体する順番
やタイミングが非常に難しい。コンパイラを書くときに良く出てくる DAG 程度
のデータ構造でも、気を付けないとすぐ二重 free しちゃうよ。
0821名前は開発中のものです。02/10/28 21:14ID:???
ttp://isweb43.infoseek.co.jp/art/yn515/game.gif
こういった感じのゲームを作ろうと試みています。
フィールド上をクリックすると、キャラがそこへ歩いて行くような。
ですが、障害物なんかを遠回りして避けていくようにするにはどうすれば
いいのか見当もつきません。どうしても凹んでいるところでつっかかってしまいます。
皆様のお知恵をお貸しください。おながいします。
ちなみに言語はHSPです。
0822名前は開発中のものです。02/10/28 22:37ID:???
>>821
絶対に答えが出るアルゴリズムだと A* とかかねぇ。
082382102/10/28 22:50ID:???
>822
検索してみましたが、適当なところが見つかりませんでした。
A*とはなんでしょうか?
0824名前は開発中のものです。02/10/28 23:11ID:Y1mIhqb7
クォータビューのマップで当たりをとりたいんですけど
高速なやり方ってあります?
内部的にはトップビューというのではなく、
クォータビューそのままでマップとキャラの菱形の当たりをとりたいのですけど…。
動作環境はへちょいので浮動小数点とか線分の交点などを求めないような軽いのを考えているのですが。
0825名前は開発中のものです。02/10/28 23:30ID:???
その当たり判定で何をやりたいかによると思うんだが
0826名前は開発中のものです。02/10/28 23:47ID:???
>>821
とりあえず障害物で行き詰まったら、障害物の表面に沿って
目標に到達できそうな位置まで移動してみるというのはどうか。
082782402/10/28 23:51ID:Y1mIhqb7
>>825
クォータビューのマップを主人公が歩くとき、マップと当たりをとりたいのです。
高さがない似非クォータビューなので、それほど苦労しまい、と思っていたら
あまり芳しい結果になりませんでして。
マップが歩けるような当たりなので、常時判定するという方向性で軽くしたい、とそういうことなのです。
082882102/10/28 23:55ID:???
>>826
その障害物が岩とかだったら、どっち側に避けても目的地までいけるんですが、
___ ____■=キャラ ○=クリックした場所
  / \
■ |  |○
  \_/

この場合、上を周って行こうとすると当然ひっかかっていけませんが
下を通って避ければ目的地までいけますよね。
こういう風にケースバイケースでどっち側に避けるかどうやって
判断させればいいのかがわからないんです。
わかりにくかったらスミマセン…
082982102/10/28 23:58ID:???
ずれちゃった…なんとかわかってください(汗 <図
つまり、出っ張った障害物なんかをちゃんと
キャラが通れるコースを歩いてくれるようにしたいのです
0830名前は開発中のものです。02/10/29 00:00ID:???
>>824
1)床だけの画像を描画する
2)キャラの足元付近のドットの有無で判定する
3)マップの残りとキャラを上書き描画する
0831名前は開発中のものです。02/10/29 00:05ID:???
>>828
ひっかかったら辿りかたを反転させれば?
083282402/10/29 00:24ID:UKOhyL2z
>>830
ワンダーウィッチなのでそうもいかないのですよ…。すみません。
083382102/10/29 00:28ID:???
>>831
やはりそれしかないですかねぇ…(汗
下手したら明らかに違う方向へ歩いていって、引っかかったら
今気付いたように遠回りをする…なんかスマートじゃなくないですか(・-・;;
0834名前は開発中のものです。02/10/29 00:32ID:???
>>833
それじゃ内部的に表示より先行して動かしておいて、未来の自分が
引き返してきたらその場で反転するようにすれば多少マシになるのでは。
083582102/10/29 00:34ID:???
あーなるほどぉ…それもそうですね
どうもありがとうございます。試してみます。(_ _
0836名前は開発中のものです。02/10/29 01:11ID:???
>>824
マップの床が碁盤の目のようになっていて、床の升目が全て同じ大きさ
同じ形であるなら、床の升目と全く同じ形状のイメージデータを配列
などで用意して、升目の座標と判定点の座標からイメージ内に対応する
座標を求め、その座標の点がセット状態であれば当たりとする。
0837名前は開発中のものです。02/10/29 01:19ID:???
>>828
一番いいのは、袋小路にならないマップを作ることですが。

そうもいかない、というなのなら、下の図みたいにマップを
大きなブロック(エリア)に分けてやるとか。
(いつかこの板で公開された進路探索方法)

A1 A2 A3
___  ____
  /  \
■ |B2 |○
B1 \_/ B3

C1 C2 C3

 B1 → C1 → C2 → C3 → B3
083883702/10/29 01:21ID:???
うわー、直したはずが大きくずれた。 すまん。
0839名前は開発中のものです。02/10/29 02:19ID:???
>>821
1:現在位置から目的地までの直線を引く

2:その直線が障害物と交差していたら交差した点から
移動できる方向へ直線を引いてみる(左右どちらにも行けるならどちらも)

3:枝分かれした線分はできるかぎり目的地へ向かうように折り曲げていく

4:現在の走査位置と目的地とを結ぶ直線が
走査線の角度と同じになったら1へ戻る

N:先に目的地にたどり着いた方が正解ルート

折れ曲がった位置と角度を配列に保存しておけば
それをトレースするだけ

計算中も枝分かれする直前までの移動をしていけば
迷路にでも迷い込まない限りそれほど時間はかからない
0840名前は開発中のものです。02/10/29 02:20ID:???
図解するとこう
____________
       /_,,. \-─●目的地
☆-─''''''''│~    │
     ↑\__/
     交差点

____________
        /_,,. \-─●目的地
☆-─'''''''|.│~    │
      iヽ\__/
      :  \    できるだけ目的地の方向へ
      :   \→

____________
        /_,,. \-─●目的地
☆-─'''''''|.│~    │  /
      iヽ\__/ /
      :  \__/
0841名前は開発中のものです。02/10/29 06:41ID:???
>820
解放したポインタにNULL代入するのは作法でしょう。
どうしてもめんどうなら、ちょっと気持ち悪いけど
free_something (void **p) {
free(*p);
*p=NULL;
}
func() {
free_something(&p);
//p=NULL
}
でいいのでは。
というか、そういうところで面倒くさがる人はC++を使うべきでは。
0842名前は開発中のものです。02/10/29 07:51ID:???
なんでややこしい方へ向かうかなぁ…

_______■=キャラ ○=クリックした場所
  / \
■|   |○
  \_/
    A


ひっかかりそうなところにはポインタを作っておく。
■から○へ行く時、間にポインタがあれば
まずそこへ向かうようにする。

      ■
| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
|  A             |
|                |
|________|
      ○

ポインタの捜索範囲はキャラ→クリック間の長方形。

以上!
084382102/10/29 07:52ID:???
ttp://isweb43.infoseek.co.jp/art/yn515/game2.gif
例えば、こういう場面でカーソルのあるところをクリックすると
池の周りを遠回りして歩いていきます。
ですが、このゲームのすごいところはカクカクした動きじゃなくて
ちゃんと池の形にぴったり沿って歩いていくということです。

もしよろしければ、実際にやってみていただけませんでしょうか?
見たほうが早いと思いますので…
isweb43.infoseek.co.jp/art/yn515/kyran.zip
pc9801です。
0844名前は開発中のものです。02/10/29 09:31ID:???
障害物のまわりにガイドラインのような情報をもたせて、
それに沿って移動するようにすれば?
0845名前は開発中のものです。02/10/29 11:30ID:???
今まで考えもしなかった方法がいろいろ出てくるんでおもろい。
0846名前は開発中のものです。02/10/29 12:45ID:???
      ________
      |\_______\
      | │ ___________ |
      | │|タマちゃん失踪?|│
      | │| ,,,,,,,,   ,,,,,,,,,、 |│
      | │l (゚∀゚) ,jj゚ー゚jjj |│
      | │|l´ lyl`l l´ : `i |│
      | │` ̄ ̄ ̄ ̄ ̄ ̄ |
      │ | l ̄ ̄ ̄:l: ̄ ̄ ̄l |
       \| l___:l:___l |
         ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
         __________
        ||\             \
        ||\\      まずかったかな・・・
        ||  \\     ────y────
               \\ ____ ∧ ∧∧__\     ゚ 。     .゚   チャプ
                \||______ (゚ ≡;゚Д)_____||    ,. -‐/⌒ヽ ─- 、  チャプ
                  ||     |  ヽ.    ||   (〜ミ(ω・`  \〜 ,)
                  ||     ヽ___)   ||   | ` ー‐-ミU -─‐'´ |
                        \      ヽ、..,,_    _,,.ノ
                                     ̄ ̄
0847 02/10/29 13:09ID:???
>>821
ttp://www.campus.ne.jp/~ishigami/CREATION/MAKING/index.html

を読むと多少はイメージできるかも。

2次元配列でマップを管理しているのなら,再帰関数っていうのを使って
考えていくんだけど(うまく言ったときのうれしさといったら・・・),
他の方法で管理しているとなると,上で書いているような方法しかないかな。
2次元配列を用意して,障害物のある座標に1とか入れて,再帰関数を使えばいいとは思うけど。
0848 02/10/29 13:10ID:???
>>846
まずいと思う。
こっそりかえしてきな。
084975502/10/29 13:58ID:???
>>771
759さん、ありがd。
これをヒントにがんばってみます。

>>791
ターゲット&要件によっては両立できない場合もあるんでつよ。(つД`)
0850名前は開発中のものです。02/10/29 20:23ID:???
>>823
"A star algorithm" で再検索。
0851名前は開発中のものです。02/10/29 20:32ID:???
ttp://www.geocities.com/jheyesjones/astar.html
0852名前は開発中のものです。02/10/29 20:44ID:???
>>841
> 解放したポインタにNULL代入するのは作法でしょう。
気休めに過ぎない作法なんか、やめとけよ……。

だいたい複数のポインタが同一の領域を指している環境では、そんな手は
使えないし。

> どうしてもめんどうなら
その程度の「手間」で済むのは free_something() なんてオモチャみたいな
コードだから。現実に面倒なデータ構造を操作するコードだと、そんな単純
にはいかんよ。

特にデータ構造が複雑な場合には、そのデータを辿るのがクリティカルパス
になるケースが多い(逆にクリティカルじゃなければ、そんな頑張って面倒
なデータ構造をメンテナンスなんかしないで、単純配列を全部検索、とかで
済ませられる)。

そこで「すべての要素に pointer の pointer を持たせて、二回 dereference
しましょう」ってのはかなり厳しいよ。

> というか、そういうところで面倒くさがる人はC++を使うべきでは。
全部 boost::shared_ptr にするとか? それは性能上の問題に加えて、解放の
タイミングを計るのが難しくなる(解放したつもりが、余計なところで shared_ptr
が一つ生きてた、とか)という問題がある。

もちろん「ここで最後の筈」ってことで assert() 入れてチェックすることはでき
るんだが、assert() に引っかかったときに

 じゃあ、いったいどこで参照が残ってるんだ?

っつーのは、やっぱり探すのが大変だよ。
0853名前は開発中のものです。02/10/30 00:06ID:???
>>852
>そこで「すべての要素に pointer の pointer を持たせて、二回 dereference
>しましょう」ってのはかなり厳しいよ。

PalmOSの開発環境では、ヒープメモリを確保するときにポインタのポインタしかくれない
(OS側でガベコレするため)のだけど、それでもなんとかなっているのは興味深い。
ポインタのポインタで生きていくための知恵が、Palm界では蓄積されてるのかもね。
0854名前は開発中のものです。02/10/30 00:13ID:???
>>853
それはコンパクションしたいからだろう。Win16 のグローバルヒープとか、昔の
MacOS とかもお仲間。

まっとーな MMU が使えない環境でもメモリの断片化が防げる代わりに、デ
バッグと処理速度に悪影響が出る。智恵というか、血と汗が蓄積されてると
思われ。

(俺も Win16 時代には泣いた覚えが)
0855名前は開発中のものです。02/10/30 00:33ID:???
>852
俺の場合、free後NULL代入してないだけで怒られたもんだが……。
二重ポインタっても、C言語に参照がないから代用してるだけだ。
参照で実装してもいいかもね。値渡しでfreeする関数に渡した
つもりのfree後のポインタが実は参照渡しで暗黙でNULLに
書き換わっていたとして、なんら問題あるまい?
むしろ、解放後のポインタにアクセスするという潜在的バグをつぶせる。
0856名前は開発中のものです。02/10/30 00:49ID:???
>>855
> 参照で実装してもいいかもね
C++ の参照のことを言ってるなら、初期化のタイミングの制約がキツいから、
完全にポインタの代用にはならんよ。

ポインタの実体を一つにして、常にポインタのポインタを使え主義が破綻す
るのは、「そのポインタの実体を解放してしまったら、やっぱり不正なメモリ
アクセスが検出できない」っつートコロなんだよな。そのための細工を積み
重ねると、結局 GC 実装した方が確実って話になる。
0857名前は開発中のものです。02/10/30 01:01ID:???
>856
いや、freeに一個ラッパーを掛けて、そこへ渡すポインタを
参照渡しにして関数内でNULLを代入しようってだけのことね。
実際はメモリをマネジメントするクラスなり関数郡なり作って
GCをそこで実装したほうがいい、っていうのにはもちろん同意。
0858名前は開発中のものです。02/10/30 01:49ID:???
>>857
> いや、freeに一個ラッパーを掛けて、そこへ渡すポインタを
> 参照渡しにして関数内でNULLを代入しようってだけのことね。
それでは不正なメモリアクセスの問題は解決しないんだけど。実例が
想像つかない?
0859名前は開発中のものです。02/10/30 02:18ID:???
>858
もともと不正なメモリアクセスは別問題。それは単にバグ。
>818を読む限り、単に解放済みポインタとそうでないポインタで
条件分けしたくないだけなら、NULLを代入すればいい。
NULLは解放済みを示すマークで、free(NULL)が素通りという
仕様はそのためにある。

ループのある枝分かれリストみたいのを解放するケースを
考えてるんだろうけど、そこまで来ると各ノードを直接freeで
解放しにいくのは無理でしょう。削除マーク付けといて、
後でGCで一括解放するしかない。
0860名前は開発中のものです。02/10/30 07:39ID:???
正直、メモリ管理は人間がやるべき仕事ではないような気がしますた。
生産性低くなる原因の一端。
0861名前は開発中のものです。02/10/30 08:46ID:???
しかし明示的に開放する機能が無いとメモリが無駄になり、下手すると
足りなくなる罠。メモリ確保の機能がある限り人間が管理するしかない。
0862名前は開発中のものです。02/10/30 09:22ID:???
2重開放はエラー出たりしてすぐ発見できるからあまり問題にならない
ような気がする。メモリリークは表面化しにくいから厄介なバグになるが。
086384602/10/30 12:54ID:???
素通り・・・
0864名前は開発中のものです。02/10/30 20:43ID:???
>>862
> 2重開放はエラー出たりしてすぐ発見できるからあまり問題にならない
そうでもない。

メモリ関係の問題はどれもそうなんだが、問題が出たときと原因が遙か彼方に
隔たってることが多い (二重 free なら一回目の free はどこで行ったんだ?)
から、原因を突き止めるのは大変だよ。特に微妙な条件でのみ発生するとか、
マルチスレッドや DMA が絡むと死ねる。

>>859
818 はそもそも「free() しなくても良いやん」つー例のような気がする。その
メモリ領域をプロセス内で再利用するなら free すべきだけど、コンパイラ
の型システムの情報なんかは、

 コンパイルが終わった時点でプロセス終了させるから、ちまちま free せずに
 投げ捨てろ

っつー情報だよな。

そこで労力をかけて free() したところで、

1. コンパイラのプロセスが終了するのを遅らせる
2. キャッシュを汚す
3. あまつさえ二重 free() なんてバグを埋め込んで SIGSEGV を食らった日には、
 ただのバカ

だろう。
0865名前は開発中のものです。02/10/31 00:04ID:???
>864
一回目のfreeは、無効なデータを解放するつもりでやってるんだろ?
それを問題が起こらないようにとただ消してしまうのは、
無効なデータへの不正なアクセスを隠してしまうだけだと思うが。
NULLポインタで明示的エラーを出させたほうが、安全。
落ちないバグの原因探すほうがよっぽどやっかいだろう。

こまめな解放はいらないとしても、一応プロセスの最後には明示的に
解放してやるべきだと思うが。
VC++だと、メモリリークが大量に警告されてうっとおしくない?
0866名前は開発中のものです。02/10/31 00:17ID:???
boost::shared_ptrとSTLのコンテナを使えばいいのに...
0867名前は開発中のものです。02/10/31 09:37ID:???
C#を使え
0868名前は開発中のものです。02/10/31 16:06ID:???
ません
0869名前は開発中のものです。02/10/31 18:22ID:???
か?
0870名前は開発中のものです。02/10/31 19:45ID:???
チョトマテ!

ココハ、
ゲームプログラミング相談室
デツヨ!
0871名前は開発中のものです。02/10/31 20:02ID:???
>>865
状況によるだろう。アセンブラのラベル情報とか 864 が言ってるようなコンパイラ
の型情報とかは、free したところで直後にプロセスが終了するのが目に見えてる
ので、free せずに終わらせるのもアリだ。

そこで free しても単なる自己満足。ユーザにとっては、むしろ邪魔なだけ。
0872名前は開発中のものです。02/11/01 00:07ID:???
>871
ちょいまち、ユーザの「邪魔」って、具体的にはなんのことだ?
ユーザには関係ない、というのなら分かるんだが。

あとでメンテナンスする人のこと考えたらメモリリークつぶすくらいは
常識だと思うがな。大量の警告メッセージに埋もれて、つぶすべき
メモリリークが見えにくくなる。
0873名前は開発中のものです。02/11/01 00:32ID:???
>>872
> ちょいまち、ユーザの「邪魔」って、具体的にはなんのことだ?
キャッシュを汚すわ、終了に(本来不要なはずの)余計な時間を食うわ、
開発コストは上がるわ。

> あとでメンテナンスする人のこと考えたらメモリリークつぶすくらいは
> 常識だと思うがな。
プロセスの寿命とデータの寿命が一致してる場合にはメモリリークとは言わん
だろ。メモリリークというのはその名の通り「漏れ」であって、使えないメモリ領
域が増えることを指すわけで。

> 大量の警告メッセージに埋もれて
_CrtSetDbgFlag() なんかが実装してる「終了時に free してないメモリ領域の
一覧を表示する」機能のこと? あれはそれなりに便利だが、万能じゃない。

(っつか BoundsCheker 使え)
0874名前は開発中のものです。02/11/01 00:44ID:???
>873
OSに暗黙的に解放してもらったって時間は掛かるだろ。
開発コストったって、ただメモリ確保に一枚ラッパーかませて
最悪の場合でも終了処理で明示的に解放されるように作るだけだろ。

その「万能じゃない」機能をさらに使いにくくしてどうするのだ。
俺は引き継いだソースがメモリリーク放置していたら、
ちょっとウンザリするがな。
0875名前は開発中のものです。02/11/01 00:54ID:26Va0gRH
この流れに便乗して質問させてください。

VC++でシューティングゲームを作っているのですが、敵や弾をたくさん表示させては
消すために、メモリをnew、deleteしまくっているのです。
ところが、実行しているとすぐに重くなってしまいます。

メモリリークに関しては、デバッグモードで
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF)
を呼び出して確認したのですが、一つもありませんでした。

これって、ちゃんと解放していても、メモリの確保が原因で重くなることってあるのですか?
ちなみに、表示させたオブジェクト(newしたインスタンス)の数に比例して
重くなっていくことは確認しました。
0876名前は開発中のものです。02/11/01 01:02ID:???
>>875
> 表示させたオブジェクト(newしたインスタンス)の数に比例して
それって、ふつうに処理量が増えてるんじゃないの?
0877名前は開発中のものです。02/11/01 01:23ID:???
>>875
敵や弾の画面表示だけしない場合も重くなるか?
■ このスレッドは過去ログ倉庫に格納されています