GetCommandLine() の戻り値に関して

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
彦左衛門

GetCommandLine() の戻り値に関して

#1 投稿記事 by 彦左衛門 »

こんにちは。

GetCommandLine() の戻り値が文字列のポインタなのは分かるのですが、
これを開放する必要は無いのでしょうか。
また、開放しても良いのでしょうか。

宜しくお願い致します。
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

Re: GetCommandLine() の戻り値に関して

#2 投稿記事 by 淡幻星 »

> GetCommandLine() の戻り値が文字列のポインタなのは分かるのですが、
> これを開放する必要は無いのでしょうか。
> また、開放しても良いのでしょうか。
開放する必要はありません。
開放しようとしてもたぶんエラーします(試してませんが)。
プログラム終了時に勝手に開放されます。
彦左衛門

Re: GetCommandLine() の戻り値に関して

#3 投稿記事 by 彦左衛門 »

淡幻星さん、大変素早い御返信有難う御座います。

>>開放しようとしてもたぶんエラーします(試してませんが)。

エラーしません(試しました)です。

>>プログラム終了時に勝手に開放されます。

開放してもしなくてもエラーも何も出ないので。

宜しければ、この戻り値の文字列の操作に関しての可否も教えて頂けますか。
GetProcessHeap() のハンドルで結構操作出来ちゃったりしますし。

それと、Ver.4.23 ですが、
calloc したのを開放しなくてもエラーも何も出ませんよね。
これってどうなんでしょう。

とりあえず、有難う御座いました。
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

Re: GetCommandLine() の戻り値に関して

#4 投稿記事 by 淡幻星 »

> 開放してもしなくてもエラーも何も出ないので。
> calloc したのを開放しなくてもエラーも何も出ませんよね。
> これってどうなんでしょう。
基本的に、開放を忘れてもエラーにはなりません(確か)。
エラーが出ないので、メモリリークしていること気づきにくく、そこが問題なのです。
> 宜しければ、この戻り値の文字列の操作に関しての可否も教えて頂けますか。
> GetProcessHeap() のハンドルで結構操作出来ちゃったりしますし。
GetProcessHeap()を用いてどういう操作をされているのか分かりませんが、
私の場合はGetCommandLine()で得たバッファは弄らないようにしています。
(このバッファはプログラムが、つまりはOSが自動で確保と開放を
 行っているので手を出すものじゃない、と思っています。
 ・・・が、確証はないので、時間があったらコノ後調べてみます^^;)


具体的には、別途に用意したバッファにコマンドラインをコピーし、
操作するのはそのコピーしたほうのみ、ってしてます。

コード: 全て選択

Dim pArgv As BytePtr
Dim pMark AS BytePtr

pMark = GetCommandLine()
pArgv = calloc( lstrlen(pMark)+1 )
lstrcpy( pArgv, pMark ) '内容をコピー
pMark = NULL '以下、pMarkには、つまりはGetCommandLine()で得たポインタには触れない。

  '・・・コマンドライン引数に対する操作は、pArgvに対して行う。・・・

free( pArgv ) '自前で確保したバッファは、キチンと開放するのが礼儀。
・・・答えになったでしょうか?(^^;)
彦左衛門

Re: GetCommandLine() の戻り値に関して

#5 投稿記事 by 彦左衛門 »

お早う御座います。

淡幻星さん、御返信有難う御座います。

>>基本的に、開放を忘れてもエラーにはなりません(確か)。

ずっと思っているのですが、エラーを出して頂けないものかと。
最近は 確保 → 開放 が慣れてきたのでアレですが、
初めの頃は忘れてばかりだったですし。

>>GetProcessHeap()を用いてどういう操作をされているのか分かりませんが...

何が出来るかと思って HeapSize とか採ってみたりしました。
で、採れたりしたんで。

>>私の場合はGetCommandLine()で得たバッファは弄らないようにしています。
>>このバッファはプログラムが、つまりはOSが自動で確保と開放を行っているので手を出すものじゃない、と思っています。

色々調べても開放したりしているのは見つからなかったのですが、かといって明確に「開放しないで」と記されてもいなかったので如何なのかと。

>>・・・が、確証はないので...

開放したりしている人は見当たらないので間違いは無いのでしょう。


一般的な、文字列の開放・操作に関する結論として、

「自前で確保したバッファのみをキチンと開放すればよい。」

「自前で確保したバッファ以外に対しては直接操作すべきでない。」

という認識で宜しいのでしょうか。
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

Re: GetCommandLine() の戻り値に関して

#6 投稿記事 by 淡幻星 »

> ずっと思っているのですが、エラーを出して頂けないものかと。
解放忘れをエラーとして吐いてくれるコンパイラがあれば、開発はかなり楽になりますね。
・・・が、しかし難しいと思います。
ユーザーの操作などによって開放のタイミングは変わりうるので、
アプリを実行した時でないと、分かりにくいと思います。
> 何が出来るかと思って HeapSize とか採ってみたりしました。
> で、採れたりしたんで。
採れるんですか。これは吃驚。
> 色々調べても開放したりしているのは見つからなかったのですが、かといって明確に「開放しないで」と記されてもいなかったので如何なのかと。
例えば、ABのヘルプを読むと「文字列が格納されているバッファ」と
書いてあるので、GetCommandLine()でバッファを確保したわけではなく
(OSによって?)もともと確保されているバッファへのポインタを
得てきただけですから、開放を考える必要はない、と私は判断してます。
> 一般的な、文字列の開放・操作に関する結論として、
>
> 「自前で確保したバッファのみをキチンと開放すればよい。」
>
> 「自前で確保したバッファ以外に対しては直接操作すべきでない。」
>
> という認識で宜しいのでしょうか。
その認識で良いと思います。
もっと正確に言うなら、

「『開放してください』と明記されているバッファのみ開放すれば良い」

「自前で確保したバッファ以外は、OSなどによってどのタイミングで
 どんな操作がされているか分からないので、ブラックボックスとして扱い、
 書き換えなどは行わないほうが良い。」

だと思います。
もっとも、コマンドライン引数以外だと、思いつきませんが^^;)
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

簡単なStringクラス

#7 投稿記事 by 淡幻星 »

> 最近は 確保 → 開放 が慣れてきたのでアレですが、
> 初めの頃は忘れてばかりだったですし。
Stringクラスには興味があるので、簡単に作って見ました。冗談程度のものですが(^^;) 使用例はこんな感じ。
解放操作のいらないBytePtr型ってとこでしょうか。

コード: 全て選択

#N88BASIC

Dim ls As LightStringClass

ls.LsCalloc( 4 ) '任意のバッファを確保
lstrcpy( ls.LsStrPtr(), "abc" ) 'BytePtr型として扱う
Print ls.LsMakeStr() 'String型として扱う

ls.LsCalloc( 6 ) '任意のバッファを確保(以前のバッファは内部で自動解放される)。
lstrcpy( ls.LsStrPtr(), "test." ) 
Print MakeStr( ls.LsStrPtr() ) 'BytePtr型として扱う

ls.LsSet( "hogehoge" ) 'バッファ確保と文字列代入を同時に行う。
Print ls.LsMakeStr()


Sleep( 3000 )
End 'この時点でバッファは勝手に解放されます。
まぁ、String型+ZeroString()で事足りることなので、
あまり必要性は感じませんが・・・lstrcpy()とかSetByte()を直に使えるのが、
便利と言えば便利かもしれません。
最後に編集したユーザー 淡幻星 [ 2006年5月14日(日) 23:08 ], 累計 1 回
ゲスト

Re: 簡単なStringクラス

#8 投稿記事 by ゲスト »

>
> 最近は 確保 → 開放 が慣れてきたのでアレですが、
> > 初めの頃は忘れてばかりだったですし。
Stringクラスには興味があるので、簡単に作って見ました。冗談程度のものですが(^^;)
> >
> 使用例はこんな感じ。
> 解放操作のいらないBytePtr型ってとこでしょうか。
>

コード: 全て選択

#N88BASIC
> 
> Dim ls As LightStringClass
> 
> ls.LsCalloc( 4 ) '任意のバッファを確保
> lstrcpy( ls.LsStrPtr(), "abc" ) 'BytePtr型として扱う
> Print ls.LsMakeStr() 'String型として扱う
> 
> ls.LsCalloc( 6 ) '任意のバッファを確保(以前のバッファは内部で自動解放される)。
> lstrcpy( ls.LsStrPtr(), "test." ) 
> Print MakeStr( ls.LsStrPtr() ) 'BytePtr型として扱う
> 
> ls.LsSet( "hogehoge" ) 'バッファ確保と文字列代入を同時に行う。
> Print ls.LsMakeStr()
> 
> 
> Sleep( 3000 )
> End 'この時点でバッファは勝手に解放されます。
>
> まぁ、String型+ZeroString()で事足りることなので、
> あまり必要性は感じませんが・・・lstrcpy()とかSetByte()を直に使えるのが、
> 便利と言えば便利かもしれません。
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

Re: 簡単なStringクラス

#9 投稿記事 by 淡幻星 »

・・・やってしまった(汗)。
上のゲストは私のミス投稿ですm(_ _)m
彦左衛門

Re: GetCommandLine() の戻り値に関して

#10 投稿記事 by 彦左衛門 »

今晩は。

淡幻星さん、三度の御返信有難う御座います。

丁寧な返信に簡単なお礼では申し訳ないとも思いますが、

「『開放してください』と明記されているバッファのみ開放すれば良い」
「自前で確保したバッファ以外は、OSなどによってどのタイミングで
 どんな操作がされているか分からないので、ブラックボックスとして扱い、
 書き換えなどは行わないほうが良い。」

ということを、GetCommandLine() の戻り値を含めた、一般的な文字列の開放・操作に関する結論として理解し、この問題は解決とさせて頂きます。


>>かなり慣れている人でも、バッファの解放忘れは時としてやってしまうと聞きます。

かなり慣れている人とは言えない私ですが、
もし速度的に有利なのであれば、現状の BytePtr でも良いと思うのですが、
「コードの側で自動確保と開放」が在って、速度的に劣らないのであれば、
そのほうが楽ですよね。

余り関係の無い話を引き合いにしますが、
カードか何かの生体認証がクラックされるというような話を聞きました。
楽に、楽にと、機械に任せるのは簡単ですが、
現状で、機械から人間の判断力を得るのはやはり難しいのでしょう。
プログラミングも、多少の苦労は受け入れなければならないのでしょうね。

もっとも、それを克服していくのも ActiveBasic の持ち味なのかも知れませんが。


淡幻星さん、最初から最後まで、有難う御座いました。
彦左衛門

Re: GetCommandLine() の戻り値に関して

#11 投稿記事 by 彦左衛門 »

あと、気づいていたんですが、上記の
「String型を廃してStringクラスとしてキッチリ再定義しよう」
のトピックは、ひょっとしたら以下のページでではないでしょうか。
http://www.activebasic.com/forum/viewtopic.php?t=996
違っていたらすいません。

因みに、私はString型は使い始めの頃使っていましたが、
今は専ら BytePtr です。
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

Re: GetCommandLine() の戻り値に関して

#12 投稿記事 by 淡幻星 »

失礼。
しばらく家を離れていましたので、見るのが遅くなりました。
簡単なお礼では申し訳ないとも思いますが
いえいえ。後半のクラスなんぞは蛇足ですので。
お気になさらずに~。
> 「String型を廃してStringクラスとしてキッチリ再定義しよう」
> のトピックは、ひょっとしたら以下のページでではないでしょうか。
> http://www.activebasic.com/forum/viewtopic.php?t=996
> 違っていたらすいません。
そっちで議論が開始されたのですが、
山本様が「再定義しようと思っています」と述べていたのは
上記の「Single型・・・」のトピックだったのです。
なので、まぎらわしいと思いつつも、そちらを載せました。
> 因みに、私はString型は使い始めの頃使っていましたが、
> 今は専ら BytePtr です。
私の場合は、簡単な処理(一時的な文字列にたいする結合や追加など)はString型、
それ以外(でっかい文字列や全体を通して確保&利用するもの)はBytePtr型を使っています。
一時期、BytePtrのみを利用していた時期もありましたが、
ちょっとした処理をするときは、自動確保&解放してくれるString型が
やっぱり楽だと思い始めた今日この頃です。

楽に、楽にと、機械に任せるのは簡単ですが、
現状で、機械から人間の判断力を得るのはやはり難しいのでしょう。
そうですね。
しかし、機械に人間の判断力を期待する必要はないと私は思います。
期待するのは、人間の判断で抜け落ちる部分の補正。
故に、楽に楽に、と考えることは悪くは無いかと。
まぁ、どっちでもよいことですが(苦笑)。
彦左衛門

Re: GetCommandLine() の戻り値に関して

#13 投稿記事 by 彦左衛門 »

今日は。

>>山本様が「再定義しようと思っています」と述べていたのは
>>上記の「Single型・・・」のトピックだったのです。
>>なので、まぎらわしいと思いつつも、そちらを載せました。

その様な経緯が在ったのは知りませんでした。失礼しました。


BytePtr の事に関してですが、必要なバッファの程度が不明な場合には、やはり、
何というか、String型に対して不便な感じはしますね。


ありがとうございました。
返信する