スレを勃てるまでもないC/C++の質問はここで 2
>>951 Ettercapがどんなツールか知らないけど、
Linuxでコンソールなら、カーソルキーの入力を取って
ncursesか何かで描画してるんじゃない?
953 :
12MHz:2007/08/15(水) 10:32:33
ユーザへのインタラクティブなエラーメッセージ
ログ等へのエラーの記録
この2つは、
ネストの深い位置(エラーを検出したその場所)
ネストの浅い位置(何かの大きなひとまとまりの処理の結果を受け取る場所)
どちらでやるのが良いのでしょうか。
好きなほうにしろよ
そういう意味じゃない
じゃあ、どういう意味ですかー!!
私はこんなにも貴方を愛しているっていうのに!!!
面白くないよ
つまんない奴
961 :
デフォルトの名無しさん:2007/08/18(土) 22:19:42
>>856 だけど
VC++Exなんたら入れてみたけど、設定多すぎてやる気なくしたんでBCCでやってます。
えっと
異常値が出る問題だけど、ようやく解決しました。
自作のStringクラスの中にポインタをもっていてそこにnewしたメモリを紐づけている
わけですが、引数としてこのStringクラスを渡すとこのクラスのコピーが作られて
もちろんメモリと紐づいたポインタもコピーされて関数の終了とともにdeleteでメモリが
開放されていた。という次第です。
コピーコンストラクタなるものを作ってちゃんとメモリもコピーしてやったら直りました。
おまえら役に立たなさ杉だなwww
理解できない頭のくせに(笑)
自作ライブラリの不具合をソース無しで問われてもエスパー以外には回答不可かと
>>961 >862で指摘済みじゃん。しかもどんぴしゃ。
>>964 それは失礼しました。ご指摘ありがとうございます。
プログラマー共ってもうすこし同類に優しいと思ってたらそうでもないんだな
殺伐としとる
優しいよ。どんな戦場に居るんだ?
>>968 お手手繋いで仲良く微温湯に使っていたいのでしょうよ。
# 微温湯っつーか、泥沼?
>>961 おまえが馬鹿すぎる。
メンバ変数にポインタを持ち、デストラクタでdeleteしているのに、
浅いコピーをするデフォルト生成のコピーコンストラクタを許す(使う)だなんて。
971 :
デフォルトの名無しさん:2007/08/19(日) 16:03:05
開発環境
Windows XP SP2
VC++6.0
質問内容
Windowsでmallocを行った際の動作は
1.OSがヒープ領域をある程度大きく取る。
2.確保したヒープ領域内からmallocで指定したサイズで領域確保する。
といった2段階の処理が行われている。
という理解でたぶん合っていると思うのですが、現在組んでいるプログラムで、
for( ii = 0 ; ii < hogehoge ; ii++ )
{
・・・
/* 領域確保 */
hogenhoge->hoge[ii] = (char*)malloc( strlen(line) * sizeof(char) );
・・・
}
といった感じに文字列をメモリに格納する処理があるのですが、一部の処理で以下の現象が発生していて対応方法が見つからずに困っています。
デバックコンパイル(正常動作) -> 「1」で確保したヒープ領域を使い切った後に、新しいヒープ領域を確保しに行く
最適化コンパイル(異常動作) -> 「1」で確保したヒープ領域を使い切る前に、新しいヒープ領域を確保しに行く(見た感じでは99%使われていない)
デバックコンパイルしたモジュールでは正常動作するのですが、最適化コンパイルを行った場合に上記問題が発生して途中で領域確保に失敗してプログラムが止まってしまっています。
メモリの状況をチェックするのには「VM Validator」というソフトウェアを使用しています。
問題点は最適化コンパイルしたモジュールの一部の処理でヒープ領域を無駄に確保しにいくという点です。
mallocは他の場所でもあちこちで使っているのですが、ここの部分でのみ上記現象が発生していて現在苦しんでいるところです
どなたかアドバイスをよろしくおねがいします。
エスパー
hogenhoge->hoge[ii] = (char*)malloc( strlen(line) * sizeof(char) );
の部分で後からstrcpyで文字列をコピーするんだろうと思うと
hogenhoge->hoge[ii] = (char*)malloc( strlen(line) * sizeof(char) + 1 );
じゃないと、終端文字分の'\0'領域がかくほされない
>>971 とりあえず、
hogenhoge->hoge[ii] = (char*)malloc( (strlen(line)+1) * sizeof(char) );
に変えてみ。
関係ないけど、sizeof(char)はいらんだろ。
sizeof(TCHAR)とかだったら、必然性あるけど。
それにしても、C++とは思えない酷いコードだな。
>>974 いる。
あとでcharをTCHARに変えることもある。
そのときに+1なんてのはマジックナンバーになってしまう。
>>976 だったら最初からTCHARにしとけばいいじゃん。
なんのためのジェネリックテキストだよ。
978 :
971:2007/08/19(日) 17:49:31
うぉっ直りました^^;
デバック版でたまたま動いてたのはヒープ領域確保する際に初期化とかしてるのが最適化版だとしてくれないとかがあって、異なる結果になってたのかな・・・
>>975 ひどいコードですみませんorz
実のところ、掲示板に書いたコードはmallocをfor文で繰り返している部分ってのを表現したくて、その場で書いたコードだったのですが、元のコードでも指摘されたのと同じミスをしていました・・・
しかも今見なおすとforループのhogehogeと領域確保する構造体の名前がかぶっている・・・と思ったら片方はhogeとhogeの間にnが入っている・・・う〜ん質問するに当たってこんなコードのせてちゃダメですね
>>974 sizeof(char)はcharが1バイトではない処理系がもしかしたらあるかもしれないので、そういう意味でこうしてます。
TCHARってのは使ったことないのですが、charとは違った文字列の持ち方をするってことかな?
勉強してみますね^^
皆さんアドバイスありがとうございました。
>>978 うつろな記憶なんで、嘘だったら誰かフォロー頼む。
デバッグビルドだとデバッグのための領域が一緒に確保される。
なので、バッファオーバーフローしても、デバッグのため領域を食いつぶして
正常に動いてるように見えることが多い。
リリースビルドだと、余分な領域を確保しないので、
オーバーフローするとわけの分からない動きをする可能性が高い。
とかそんな話だったと思う。
>>977 TCHARとして書いていないものをTCHARとして書くのは無責任だ。
だいたい意味が分かるように書くべきであって、
型のサイズが既知で変りそうもないからハードコーディングするのはおかしい。
sizeof(DWORD)なんてのも直に4と書けと言うのか?
>>978 TCHARというのはWindowsのWin32APIのマクロで、
Win32APIのUnicode版とMCBS版を透過的に使うためのもの。
実体は、
#ifdef UNICODE
typedef wchar_t TCHAR;
#else
typedef unsigned char TCHAR;
#endif
こういうことになってる。
ちなみにVC++のランタイムライブラリでは、
#ifdef _UNICODE
typedef wchar_t _TCHAR;
#else
typedef char _TCHAR;
#endif
ということになっている。
この2つは厳密には別物であり使い分けるべきなのだけれども、
Win32APIと関係のないところで_TCHARではなくTCHARを使う人が少なくない。
>>980 デバッグビルドの場合、バッファオーバーフローを検出するための仕掛けがある。
MSDNライブラリ等で
_CrtCheckMemory
などの一連の項目を見るといい。
簡単に言うと、余分にメモリを確保して、そこに特別な値を書き込んでおき、
その値が変っているかどうかをチェックして、バッファオーバーフローを検出する。
VC++6.0のIDE上でデバッグモードで動かしていれば、
プロセスが終了する間際に、トレースの所に何かメッセージが出ていたと思うよ。
>>981 もちろんほかの箇所もTCAHR使うって前提だよ。
>>976 の「あとでsizeof(TCHAR)にすることもある」って話も、そこだけ変えるんじゃないだろ?
ハードコーディングしろって話じゃなくて、sizeof(char)は1だと決まってるんだから、そもそも、いらないって話だよ。
あとでsizeof(TCHAR)に書き直すくらいなら、最初からそう書いておけばいい。
>>984 ただ単に
1
と書いたら、意味がわかりにくい。
もう一度聞くが、
sizeof(DWORD)も4と書くのか?
誰が1や4と書くなんて書いとんねん
つまらない事で言い合いスンナ!
987 :
971:2007/08/19(日) 19:19:18
>>980 おお〜なんか納得できる^^
sizeof(char)に関しては、
>>981さんの考え方に近いかな〜
昔32bit -> 64bitの移植に携わったことがあって、その時にちと苦しめられたので明示的に書くようにしてます^^
具体的にはポインタの領域確保するのに、(たぶん組んだ人は動きゃいいやという考え方で適当に組んでいたダメ人間)sizeof(int)使って領域確保してて、
32bitだとポインタもintも両方同じ4バイトだからちゃんと動作するんだけど、
64bitではポインタだけ8バイトに変わるから、そこの部分でエラーが出て、
しかもコピーして使いまわしたらしく同じようなコードがあちこちに点在してて・・・
今となってはいい思い出だけど、あれは大変だったなぁ〜(-_-;)
今回のケースとは大分違うんだけど、明示的に書いておいた方が将来的にどんなふうに仕様が変化するか分からないし安全だなぁ〜って教訓からこうしてます^^
TCHARも知らん分際で何ホザいとんねん
>>985 だから「いらない」って言ってるじゃん。
malloc(strlen(s) * 1) こんな書き方しろなんて言ってないよ。
もうスレが終わりそうだからマトメ
(a) malloc(tcslen(s) * sizeof(TCHAR)) なら普通の書き方。
(b) malloc(strlen(s) * sizeof(char)) のsizeof(char)は意味がない。
あとでcharをTCHARに変えるかもって想定してるなら、この使い方はマジックナンバーを
埋め込んでるより多少はマシだけど、まあ大差ないレベル。
最初から (a)の書き方をするべき。
>>989 malloc(strlen(s)+1)
こんな書き方をしたら、気持ち悪いだろ。
mallocが受け取るのは「文字数」ではなく「バイト数」だ。
strlenが返すのは「バイト数」ではなく「文字数」だ。それは+1しても、「文字数」のままだ。
「バイト数」を受け取るところに、「文字数」を渡すのは、気持ち悪すぎる。
sizeof(char)に「文字数」を掛けることで、適切に「文字数」を「バイト数」に変換できる。
だから、たとえsizeof(char)が1だとわかりきっていても、それを省略すべきではない。
>>991 99%の確率でバグっているコードを「普通の書き方」なんて言うな。
>sizeof(char)に「文字数」を掛けることで、適切に「文字数」を「バイト数」に変換できる。
いいえ。
ツマンネェ奴ら
>>977 は
>>974 でしょ?
元もとstrlenだけで十分だと言ってるんだと思うが...
もし、つけるんだったらsizeof(*line) じゃだめか?
>>993 元のコードにあわせただけ。
この話の本筋とは関係ないし。
マイナーな本でsizeof(char)を使えって薦めてるのを見たことあるけど、
まあ、こういうスタイルは、圧倒的に少数派。
こんなクセのある書き方を推奨するやつは、コードを読んで無さ杉。
998 :
971:2007/08/19(日) 19:54:19
なんかスレが荒れてしまって申し訳ないです。
皆さん善意で書き込んでくださっているわけなので、感謝してます。
ただ個々人で使用し続けてきたコーディングのスタイルがあって、それでいい争いになってしまっていて、すれが険悪になってしまって申し訳ありません。
今回の件ではバグが取れたという以外にも、文字列絡みの処理に対して再勉強する機会になったのでよかったです。
↓1000
呼んだ?
1001 :
1001:
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。