GetCommandLine() の戻り値に関して
GetCommandLine() の戻り値に関して
こんにちは。
GetCommandLine() の戻り値が文字列のポインタなのは分かるのですが、
これを開放する必要は無いのでしょうか。
また、開放しても良いのでしょうか。
宜しくお願い致します。
GetCommandLine() の戻り値が文字列のポインタなのは分かるのですが、
これを開放する必要は無いのでしょうか。
また、開放しても良いのでしょうか。
宜しくお願い致します。
Re: GetCommandLine() の戻り値に関して
開放する必要はありません。> GetCommandLine() の戻り値が文字列のポインタなのは分かるのですが、
> これを開放する必要は無いのでしょうか。
> また、開放しても良いのでしょうか。
開放しようとしてもたぶんエラーします(試してませんが)。
プログラム終了時に勝手に開放されます。
Re: GetCommandLine() の戻り値に関して
淡幻星さん、大変素早い御返信有難う御座います。
>>開放しようとしてもたぶんエラーします(試してませんが)。
エラーしません(試しました)です。
>>プログラム終了時に勝手に開放されます。
開放してもしなくてもエラーも何も出ないので。
宜しければ、この戻り値の文字列の操作に関しての可否も教えて頂けますか。
GetProcessHeap() のハンドルで結構操作出来ちゃったりしますし。
それと、Ver.4.23 ですが、
calloc したのを開放しなくてもエラーも何も出ませんよね。
これってどうなんでしょう。
とりあえず、有難う御座いました。
>>開放しようとしてもたぶんエラーします(試してませんが)。
エラーしません(試しました)です。
>>プログラム終了時に勝手に開放されます。
開放してもしなくてもエラーも何も出ないので。
宜しければ、この戻り値の文字列の操作に関しての可否も教えて頂けますか。
GetProcessHeap() のハンドルで結構操作出来ちゃったりしますし。
それと、Ver.4.23 ですが、
calloc したのを開放しなくてもエラーも何も出ませんよね。
これってどうなんでしょう。
とりあえず、有難う御座いました。
Re: GetCommandLine() の戻り値に関して
> 開放してもしなくてもエラーも何も出ないので。
基本的に、開放を忘れてもエラーにはなりません(確か)。> 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() の戻り値に関して
お早う御座います。
淡幻星さん、御返信有難う御座います。
>>基本的に、開放を忘れてもエラーにはなりません(確か)。
ずっと思っているのですが、エラーを出して頂けないものかと。
最近は 確保 → 開放 が慣れてきたのでアレですが、
初めの頃は忘れてばかりだったですし。
>>GetProcessHeap()を用いてどういう操作をされているのか分かりませんが...
何が出来るかと思って HeapSize とか採ってみたりしました。
で、採れたりしたんで。
>>私の場合はGetCommandLine()で得たバッファは弄らないようにしています。
>>このバッファはプログラムが、つまりはOSが自動で確保と開放を行っているので手を出すものじゃない、と思っています。
色々調べても開放したりしているのは見つからなかったのですが、かといって明確に「開放しないで」と記されてもいなかったので如何なのかと。
>>・・・が、確証はないので...
開放したりしている人は見当たらないので間違いは無いのでしょう。
一般的な、文字列の開放・操作に関する結論として、
「自前で確保したバッファのみをキチンと開放すればよい。」
「自前で確保したバッファ以外に対しては直接操作すべきでない。」
という認識で宜しいのでしょうか。
淡幻星さん、御返信有難う御座います。
>>基本的に、開放を忘れてもエラーにはなりません(確か)。
ずっと思っているのですが、エラーを出して頂けないものかと。
最近は 確保 → 開放 が慣れてきたのでアレですが、
初めの頃は忘れてばかりだったですし。
>>GetProcessHeap()を用いてどういう操作をされているのか分かりませんが...
何が出来るかと思って HeapSize とか採ってみたりしました。
で、採れたりしたんで。
>>私の場合はGetCommandLine()で得たバッファは弄らないようにしています。
>>このバッファはプログラムが、つまりはOSが自動で確保と開放を行っているので手を出すものじゃない、と思っています。
色々調べても開放したりしているのは見つからなかったのですが、かといって明確に「開放しないで」と記されてもいなかったので如何なのかと。
>>・・・が、確証はないので...
開放したりしている人は見当たらないので間違いは無いのでしょう。
一般的な、文字列の開放・操作に関する結論として、
「自前で確保したバッファのみをキチンと開放すればよい。」
「自前で確保したバッファ以外に対しては直接操作すべきでない。」
という認識で宜しいのでしょうか。
Re: GetCommandLine() の戻り値に関して
解放忘れをエラーとして吐いてくれるコンパイラがあれば、開発はかなり楽になりますね。> ずっと思っているのですが、エラーを出して頂けないものかと。
・・・が、しかし難しいと思います。
ユーザーの操作などによって開放のタイミングは変わりうるので、
アプリを実行した時でないと、分かりにくいと思います。
蛇足。 [ここをクリックすると内容が表示されます]
かなり慣れている人でも、バッファの解放忘れは時としてやってしまうと聞きます。
ミスは人間としてしょうがないので、であればコードの側で自動確保と開放を
してしまえば、コーディングの際に解放を気にする必要は無く、
結果として忘れることもなくなる、という話になります。
その結果として生まれてきたのが、
文字列に関していえばC++のStringクラスであり、
もっと広くはスマートポインタになります。
ABのString型も、この仲間ですね(自動で解放される)。
・・・仕様があいまいなのが欠点(APIとの相性悪し)。
ちなみに、String型を廃してStringクラスとしてキッチリ再定義しよう
という動きがあるみたいです。
ミスは人間としてしょうがないので、であればコードの側で自動確保と開放を
してしまえば、コーディングの際に解放を気にする必要は無く、
結果として忘れることもなくなる、という話になります。
その結果として生まれてきたのが、
文字列に関していえばC++のStringクラスであり、
もっと広くはスマートポインタになります。
ABのString型も、この仲間ですね(自動で解放される)。
・・・仕様があいまいなのが欠点(APIとの相性悪し)。
ちなみに、String型を廃してStringクラスとしてキッチリ再定義しよう
という動きがあるみたいです。
採れるんですか。これは吃驚。> 何が出来るかと思って HeapSize とか採ってみたりしました。
> で、採れたりしたんで。
例えば、ABのヘルプを読むと「文字列が格納されているバッファ」と> 色々調べても開放したりしているのは見つからなかったのですが、かといって明確に「開放しないで」と記されてもいなかったので如何なのかと。
書いてあるので、GetCommandLine()でバッファを確保したわけではなく
(OSによって?)もともと確保されているバッファへのポインタを
得てきただけですから、開放を考える必要はない、と私は判断してます。
その認識で良いと思います。> 一般的な、文字列の開放・操作に関する結論として、
>
> 「自前で確保したバッファのみをキチンと開放すればよい。」
>
> 「自前で確保したバッファ以外に対しては直接操作すべきでない。」
>
> という認識で宜しいのでしょうか。
もっと正確に言うなら、
「『開放してください』と明記されているバッファのみ開放すれば良い」
「自前で確保したバッファ以外は、OSなどによってどのタイミングで
どんな操作がされているか分からないので、ブラックボックスとして扱い、
書き換えなどは行わないほうが良い。」
だと思います。
もっとも、コマンドライン引数以外だと、思いつきませんが^^;)
簡単なStringクラス
Stringクラスには興味があるので、簡単に作って見ました。冗談程度のものですが(^^;)> 最近は 確保 → 開放 が慣れてきたのでアレですが、
> 初めの頃は忘れてばかりだったですし。
クラス定義はこちらです。 [ここをクリックすると内容が表示されます]
使用例はこんな感じ。コード: 全て選択
'簡単なStringクラス。お遊び~。
Class LightStringClass
pBuffer As BytePtr
strBuffer As String
Public
Sub LightStringClass()
pBuffer = NULL
End Sub
Sub ~LightStringClass()
DeleteBuffer()
End Sub
Sub DeleteBuffer()
If( pBuffer<>NULL )Then
free( pBuffer )
pBuffer = NULL
End If
End Sub
'任意のバッファを確保
Function LsCalloc( nByte As Long ) As Long
DeleteBuffer()
pBuffer = calloc( nByte )
If( pBuffer<>NULL )Then
LsCalloc = TRUE
Else
LsCalloc = FALSE
End If
End Function
'文字列をBytePtr型として返す。
Function LsStrPtr() As BytePtr
LsStrPtr = pBuffer
End Function
'バッファの確保と文字列を代入を同時に行う。
Function LsSet( pMark As BytePtr ) As Long
LsSet = LsCalloc( lstrlen(pMark)+1 )
If( LsSet=FALSE )Then
ExitFunction
Else
If( NULL=lstrcpy( pBuffer, pMark ) )Then
LsSet = FALSE
End If
End If
End Function
'文字列をString型として返す。
Function LsMakeStr() As String
strBuffer = MakeStr( pBuffer )
LsMakeStr = strBuffer
End Function
End Class
解放操作のいらない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 'この時点でバッファは勝手に解放されます。
あまり必要性は感じませんが・・・lstrcpy()とかSetByte()を直に使えるのが、
便利と言えば便利かもしれません。
最後に編集したユーザー 淡幻星 [ 2006年5月14日(日) 23:08 ], 累計 1 回
Re: 簡単なStringクラス
>
>
> 使用例はこんな感じ。
> 解放操作のいらないBytePtr型ってとこでしょうか。
>
>
> まぁ、String型+ZeroString()で事足りることなので、
> あまり必要性は感じませんが・・・lstrcpy()とかSetByte()を直に使えるのが、
> 便利と言えば便利かもしれません。
Stringクラスには興味があるので、簡単に作って見ました。冗談程度のものですが(^^;)> 最近は 確保 → 開放 が慣れてきたのでアレですが、
> > 初めの頃は忘れてばかりだったですし。
>
クラス定義はこちらです。 [ここをクリックすると内容が表示されます]
> コード: 全て選択
'簡単なStringクラス。お遊び~。
> Class LightStringClass
> pBuffer As BytePtr
> strBuffer As String
> Public
> Sub LightStringClass()
> pBuffer = NULL
> End Sub
> Sub ~LightStringClass()
> DeleteBuffer()
> End Sub
>
> Sub DeleteBuffer()
> If( pBuffer<>NULL )Then
> free( pBuffer )
> pBuffer = NULL
> End If
> End Sub
>
> '任意のバッファを確保
> Function LsCalloc( nByte As Long ) As Long
> DeleteBuffer()
> pBuffer = calloc( nByte )
> If( pBuffer<>NULL )Then
> LsCalloc = TRUE
> Else
> LsCalloc = FALSE
> End If
> End Function
>
> '文字列をBytePtr型として返す。
> Function LsStrPtr() As BytePtr
> LsStrPtr = pBuffer
> End Function
>
> 'バッファの確保と文字列を代入を同時に行う。
> Function LsSet( pMark As BytePtr ) As Long
> LsSet = LsCalloc( lstrlen(pMark)+1 )
> If( LsSet=FALSE )Then
> ExitFunction
> Else
> If( NULL=lstrcpy( pBuffer, pMark ) )Then
> LsSet = FALSE
> End If
> End If
> End Function
>
> '文字列をString型として返す。
> Function LsMakeStr() As String
> strBuffer = MakeStr( pBuffer )
> LsMakeStr = strBuffer
> End Function
>
> End Class
> 使用例はこんな感じ。
> 解放操作のいらない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()を直に使えるのが、
> 便利と言えば便利かもしれません。
Re: 簡単なStringクラス
・・・やってしまった(汗)。
上のゲストは私のミス投稿ですm(_ _)m
上のゲストは私のミス投稿ですm(_ _)m
Re: GetCommandLine() の戻り値に関して
今晩は。
淡幻星さん、三度の御返信有難う御座います。
丁寧な返信に簡単なお礼では申し訳ないとも思いますが、
「『開放してください』と明記されているバッファのみ開放すれば良い」
「自前で確保したバッファ以外は、OSなどによってどのタイミングで
どんな操作がされているか分からないので、ブラックボックスとして扱い、
書き換えなどは行わないほうが良い。」
ということを、GetCommandLine() の戻り値を含めた、一般的な文字列の開放・操作に関する結論として理解し、この問題は解決とさせて頂きます。
>>かなり慣れている人でも、バッファの解放忘れは時としてやってしまうと聞きます。
かなり慣れている人とは言えない私ですが、
もし速度的に有利なのであれば、現状の BytePtr でも良いと思うのですが、
「コードの側で自動確保と開放」が在って、速度的に劣らないのであれば、
そのほうが楽ですよね。
余り関係の無い話を引き合いにしますが、
カードか何かの生体認証がクラックされるというような話を聞きました。
楽に、楽にと、機械に任せるのは簡単ですが、
現状で、機械から人間の判断力を得るのはやはり難しいのでしょう。
プログラミングも、多少の苦労は受け入れなければならないのでしょうね。
もっとも、それを克服していくのも ActiveBasic の持ち味なのかも知れませんが。
淡幻星さん、最初から最後まで、有難う御座いました。
淡幻星さん、三度の御返信有難う御座います。
丁寧な返信に簡単なお礼では申し訳ないとも思いますが、
「『開放してください』と明記されているバッファのみ開放すれば良い」
「自前で確保したバッファ以外は、OSなどによってどのタイミングで
どんな操作がされているか分からないので、ブラックボックスとして扱い、
書き換えなどは行わないほうが良い。」
ということを、GetCommandLine() の戻り値を含めた、一般的な文字列の開放・操作に関する結論として理解し、この問題は解決とさせて頂きます。
>>かなり慣れている人でも、バッファの解放忘れは時としてやってしまうと聞きます。
かなり慣れている人とは言えない私ですが、
もし速度的に有利なのであれば、現状の BytePtr でも良いと思うのですが、
「コードの側で自動確保と開放」が在って、速度的に劣らないのであれば、
そのほうが楽ですよね。
余り関係の無い話を引き合いにしますが、
カードか何かの生体認証がクラックされるというような話を聞きました。
楽に、楽にと、機械に任せるのは簡単ですが、
現状で、機械から人間の判断力を得るのはやはり難しいのでしょう。
プログラミングも、多少の苦労は受け入れなければならないのでしょうね。
もっとも、それを克服していくのも ActiveBasic の持ち味なのかも知れませんが。
淡幻星さん、最初から最後まで、有難う御座いました。
Re: GetCommandLine() の戻り値に関して
あと、気づいていたんですが、上記の
「String型を廃してStringクラスとしてキッチリ再定義しよう」
のトピックは、ひょっとしたら以下のページでではないでしょうか。
http://www.activebasic.com/forum/viewtopic.php?t=996
違っていたらすいません。
因みに、私はString型は使い始めの頃使っていましたが、
今は専ら BytePtr です。
「String型を廃してStringクラスとしてキッチリ再定義しよう」
のトピックは、ひょっとしたら以下のページでではないでしょうか。
http://www.activebasic.com/forum/viewtopic.php?t=996
違っていたらすいません。
因みに、私はString型は使い始めの頃使っていましたが、
今は専ら BytePtr です。
Re: GetCommandLine() の戻り値に関して
失礼。
しばらく家を離れていましたので、見るのが遅くなりました。
お気になさらずに~。
山本様が「再定義しようと思っています」と述べていたのは
上記の「Single型・・・」のトピックだったのです。
なので、まぎらわしいと思いつつも、そちらを載せました。
それ以外(でっかい文字列や全体を通して確保&利用するもの)はBytePtr型を使っています。
一時期、BytePtrのみを利用していた時期もありましたが、
ちょっとした処理をするときは、自動確保&解放してくれるString型が
やっぱり楽だと思い始めた今日この頃です。
しかし、機械に人間の判断力を期待する必要はないと私は思います。
期待するのは、人間の判断で抜け落ちる部分の補正。
故に、楽に楽に、と考えることは悪くは無いかと。
まぁ、どっちでもよいことですが(苦笑)。
しばらく家を離れていましたので、見るのが遅くなりました。
いえいえ。後半のクラスなんぞは蛇足ですので。簡単なお礼では申し訳ないとも思いますが
お気になさらずに~。
そっちで議論が開始されたのですが、> 「String型を廃してStringクラスとしてキッチリ再定義しよう」
> のトピックは、ひょっとしたら以下のページでではないでしょうか。
> http://www.activebasic.com/forum/viewtopic.php?t=996
> 違っていたらすいません。
山本様が「再定義しようと思っています」と述べていたのは
上記の「Single型・・・」のトピックだったのです。
なので、まぎらわしいと思いつつも、そちらを載せました。
私の場合は、簡単な処理(一時的な文字列にたいする結合や追加など)はString型、> 因みに、私はString型は使い始めの頃使っていましたが、
> 今は専ら BytePtr です。
それ以外(でっかい文字列や全体を通して確保&利用するもの)はBytePtr型を使っています。
一時期、BytePtrのみを利用していた時期もありましたが、
ちょっとした処理をするときは、自動確保&解放してくれるString型が
やっぱり楽だと思い始めた今日この頃です。
そうですね。楽に、楽にと、機械に任せるのは簡単ですが、
現状で、機械から人間の判断力を得るのはやはり難しいのでしょう。
しかし、機械に人間の判断力を期待する必要はないと私は思います。
期待するのは、人間の判断で抜け落ちる部分の補正。
故に、楽に楽に、と考えることは悪くは無いかと。
まぁ、どっちでもよいことですが(苦笑)。
Re: GetCommandLine() の戻り値に関して
今日は。
>>山本様が「再定義しようと思っています」と述べていたのは
>>上記の「Single型・・・」のトピックだったのです。
>>なので、まぎらわしいと思いつつも、そちらを載せました。
その様な経緯が在ったのは知りませんでした。失礼しました。
BytePtr の事に関してですが、必要なバッファの程度が不明な場合には、やはり、
何というか、String型に対して不便な感じはしますね。
ありがとうございました。
>>山本様が「再定義しようと思っています」と述べていたのは
>>上記の「Single型・・・」のトピックだったのです。
>>なので、まぎらわしいと思いつつも、そちらを載せました。
その様な経緯が在ったのは知りませんでした。失礼しました。
BytePtr の事に関してですが、必要なバッファの程度が不明な場合には、やはり、
何というか、String型に対して不便な感じはしますね。
ありがとうございました。