[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 1001- 2chのread.cgiへ]
Update time : 06/03 14:53 / Filesize : 254 KB / Number-of Response : 1002
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

【初心者歓迎】C/C++室 Ver.69【環境依存OK】



1 名前:デフォルトの名無しさん mailto:sage [2009/10/20(火) 16:10:55 ]
エスケープシーケンスやWin32APIなどの環境依存なものでもOK。
ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。

【前スレ】
【初心者歓迎】C/C++室 Ver.68【環境依存OK】
pc12.2ch.net/test/read.cgi/tech/1253193779/

【アップローダー】(質問が長い時はココ使うと便利)
kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm
codepad.org/ (コンパイルもできるし出力結果も得られるのでお勧め)

◆ソースのインデントについて
半角空白やTABでのインデントはスレに貼ると無くなります。
そのため、アップローダーに上げるのも手ですが直接貼る場合は、
全角空白か   に置換すると見栄えだけはよくなります。

664 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 12:14:43 ]
>>663
x86系CPU+Visual C++では、そう(doubleじゃなくてlong doubleだけど)。
x64だとちょっと違ってて、多分floatで計算してると思う。

詳しくはx87FPUとSSE演算を調べてみてくれ。
重要なのはx64+WindowsだとFPUレジスタがDisableされていること。

665 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 13:50:25 ]
>>660
プロジェクトに悪意あるメンバーがいたらメモリリークさせられるぞ

666 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 13:59:53 ]
悪気は無かったんです・・・

667 名前:デフォルトの名無しさん [2009/11/11(水) 14:25:35 ]
VC++のMFCアプリで、あるjavaアプレットの画面イメージを取得するため
対象ウィンドウを検索して存在すればCWnd::SetWindowPos()で最前面にもってきて
CWnd::RedrawWindow()で再描画、ということを行っています。
対象ウィンドウが他のウィンドウに隠れている場合はこれでいいんですが
もともと最前面にある場合は、再描画の処理は不要だと思うのでスキップしたいのですが
最前面であるかどうかはどう判断すれば良いのでしょうか?
CWnd::GetWindow()でいろいろやってみているんですがうまくいきません。

668 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 15:41:34 ]
>>664
>x64+WindowsだとFPUレジスタがDisableされていること。

されてねえよ
タスクスイッチの時もスレッド切り替えの時もちゃんとFPUはsaveするように
仕様が変わった

669 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 16:06:54 ]
>>667
::EnumWindows()とかでどうか
不安ならそれに::GetWindow()を組み合わせる

670 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 16:24:15 ]
独学でCを学んでいます。
2進数から10進数への変換方法がわかったので
入力した2進数を10進数で表示する関数を作ったのですが
32桁あるときだけ答えが空白になってしまいます。
問題がある箇所を教えてください、お願いします。
環境はxp homeのvisual studio 2005です。

kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10099.txt

671 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 16:58:16 ]
ソース1とソース2のコストは同じでしょうか?
CPUのコストはわかりませんが、少なくともメモリの使用量は同じに見えますが、どうでしょうか?
1: //ソース1
2: for(int i=0; i<10; i++){
3:  for(int j=0; j<10; j++){
4:   static const float x = 10;
5:   //処理省略
6:  }
7: }
8: //ソース2
9: static const float x = 10;
10: for(int i=0; i<10; i++){
11:  for(int j=0; j<10; j++){
12:   //処理省略
13:  }
14: }

672 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:21:01 ]
>>671
コンパイラと環境によって違いますとしか言えない

最適化が優れたコンパイラなら float x そのものを消去してしまうと思う



673 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:31:12 ]
使用していない変数は消去ってやつですね。
処理省略の部分でxは使っている事とします。
変数は静的な領域に確保するわけですから、どのコンパイラでもメモリの使用量はかわらないように見えるんですが、違うのでしょうか?

674 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:33:00 ]
>>673
そうとも言えない
とにかくコンパイラの吐いたコードを見るしか確かめる手はない

675 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:33:52 ]
>>671
横から、付け加えるなら、省略された部分の処理内容も影響する。
場合によっちゃあ処理フローまでガラッと変わる。

676 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:33:57 ]
あ、xは使ってるのか
それなら変わらないだろうという予測が立つ
しかしあくまでも予測だという事を忘れないように

677 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:36:51 ]
>>673
言語仕様では、静的変数の振舞は定義されていても、実装方法までは定義されていないので、
本当に静的な領域に確保されるかどうかは、コンパイラの出力したコードを見ないとわからない。
もっとも、一度確認したからといって、次にコンパイルしたときは違う結果になっているかもしれない。

678 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:39:07 ]
x86/x64のVCやgccなら、たぶん即値として命令コードに埋め込まれちゃう。
あくまで予測ですがね。

679 名前:671 mailto:sage [2009/11/11(水) 18:25:50 ]
私のレベルからしてコンパイラが吐いたコードを解析するのは無理です。
コストに関しては曖昧な感じですし
for文の中に書くと気持ち悪いので、forの中でしか使わない定数でも外だししときます。

ありがとうございました。

680 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 18:46:12 ]
for(int i = 0, const float x = 10; i < 10; ++i)

つーか80:20の(ry

681 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 19:02:03 ]
>>679
>for文の中に書くと気持ち悪いので、forの中でしか使わない定数でも外だししときます。
そりゃ逆だ。
「スコープはなるべく小さく」といわれている。


682 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 19:03:20 ]
L2キャッシュが良く効くからな



683 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 19:04:03 ]
じゃなかった、バグが減るからか
C++はスマポがあるからいいんだが

684 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 20:45:41 ]
嘘みたいな話だが、昔の gcc だとスコープ狭い方が良
いコードが出た(龍本レベルでもあり得ないと思うんだ
が…)。

しかしまぁ、人間にとってもスコープ狭い方が読むとき
に気にすべき情報が減るので読み易い。

685 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 21:48:52 ]
{
const int c = 10;

for(int j = 0; ・・・

}

でもこれってちょっとダサくない?
インデント深くなるし

686 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 22:05:04 ]
慣れればスコープ無視したコードの方がダサイと思うようになるさ

687 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 22:34:36 ]
コピーコンストラクタとoperator=()の内容って同じことが多いのですが、
コピーコンストラクタには「*this = コピー元;」とだけ書いて
operator=()のほうに処理を集約してしまうことって、なにかまずいことはありますか?

688 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 22:40:08 ]
俺もよく使うな、自動変数の生存範囲を限定するためだけのスコープ。

689 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 22:40:42 ]
場合によってはバグの元になる
ならなくてもメンバ変数が全部初期化された後
すぐに代入することになるから無駄な処理が発生する


690 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 02:14:40 ]
>>687
コピーコンストラクタと代入演算子で2つも似たような処理を書きたくないのなら、
逆にコピーコンストラクタ(とswap)を使ってoperator =を実装するほうがおすすめ。こんな感じ。
class Hoge
{
Hoge(const Hoge&); //コピーコンストラクタ
void swap(Hoge& other); // *thisとotherの全メンバをswapする

Hoge& operator =(const Hoge& y)
{
Hoge(y).swap(*this);
return *this;
}

};
めちゃくちゃ新しい処理系ならswapの代わりにstd::moveを
(ムーブ代入演算子を定義して)使う方法も使えるけど、ここでは取り上げない。あしからず。

691 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 03:17:23 ]
>>690
これ未定義の動作にならない?

class Hoge
{
int i;
public:
Hoge(int ii = 0) : i(ii) {}
Hoge(const Hoge& j) : i(j.i) {} //コピーコンストラクタ
void swap(Hoge& other) { // *thisとotherの全メンバをswapする
Hoge* tmp = new Hoge;
std::memcpy(tmp, this, sizeof(*this)); // undefined behavior
std::memcpy(this, &other, sizeof(*this));
std::memcpy(&other, tmp, sizeof(*this));
}
Hoge& operator=(const Hoge& y) {
Hoge(y).swap(*this);
return *this;
}
void print() const {
std::cout << i << std::endl;
}
};

int main()
{
Hoge a(1);
Hoge b(2);
a = b;
a.print();
b.print();
}

692 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 04:00:58 ]
質問です
C++において、関数ポインタを使う意義は何があるでしょうか?
言い換えれば、具体的にどのような事をするときに便利なのでしょうか
どなたかお願いします・・・



693 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 04:48:35 ]
コールバックとか。・・・でもC++だとその多くは仮想関数に取って代わるかな?

C++でも使う例というと、関数テーブルかなぁ。
たとえば、ユーザーの入力したコマンドに応じた動作をしたい場合(以下コードは適当)、
typedef int(*Cmd)(T* args);
Cmd command = { &CommandA, &CommandB ... }; // 関数テーブル(関数ポインタのリスト)
みたいなのを用意した上で、それをこんな風に実行する。
int Execute(int cmd, T* args) { return (command[cmd])(args); } // cmdの値はユーザーの入力次第

もちろん、switch (cmd) { ... } で分岐させてもいいけど、それだと各コマンドに対応する関数を
色々切り替えたい時とかには少々不便だし、コマンドの総数が3桁だったりするとswitch文が長すぎちゃう。
まぁその辺は結局作りたい物次第なわけだけど。
世の中に無数にあるはずの、オリジナルのスクリプト言語(ゲームエンジン用でも何でも)のコードには、
関数テーブルが山ほど出てきそうだなぁ。

694 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 09:09:50 ]
最近の OO 学習から入った C++ な人は基底クラスのポ
インタ使ってれば無理に関数ポインタ使わなくてもいい
気がする。

695 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 09:36:52 ]
クラスのインスタンスのメソッドへのポインタって使えますか?

696 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 10:10:15 ]
はい

697 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 12:27:45 ]
>>692
Win32を使うと嫌でもコールバックを使う場面に出くわすよ

698 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 16:09:11 ]
>>695
使えるけど使わないほうが無難だな。 ->* とか .* とか見たくないよ。
C++的には operator()()がいいかも。

699 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 20:26:12 ]
->*は拡張メソッドで使ってしまう


700 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 21:49:51 ]
Cです
構造体の初期化でmemsetを使うと問題があると聞きました.
ループ文でまわしている場合,毎回初期化する必要があるんですが
どうすればいいんでしょうか?

ポインタ配列です.

typedef struct{


701 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 21:52:43 ]
struct Hoge hoge = {0};

702 名前:700 mailto:sage [2009/11/12(木) 21:52:57 ]
すいません.途中で送信してしまいました.
どうやって初期化すればよろしいのでしょうか?



703 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 22:24:39 ]
>>701
ありがとうございます.
実際にはポインタで宣言しているのですが,

Hoge *hoge

hoge = malloc(sizeof(Hoge) * 100);

for(i = 0; i < 100; i++){
hoge[i] = {0};
}

でいいんですかね?

704 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 22:32:05 ]
zeromemory使えや

705 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 22:53:04 ]
std::fill()使えや

706 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 22:57:05 ]
>>705
それはC++。

707 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 22:59:33 ]
>>703だけ見てCかC++か区別付くかヴォケ

708 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 23:00:04 ]
Hoge foo = {0};

for(i = 0; i < 100; i++)
hoge[i] = foo;

709 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 23:00:35 ]
C++ならmalloc()の戻り値をキャストしないのはエラーなのでは

710 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 00:44:58 ]
Hoge の中に微妙なモノが union で詰まってる時は必要
に応じて何種類か用意しておいてコピーすればいいと思
うんだけど、この場合何も考えずに {0} で初期化する
と未定義動作だっけ?

711 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 01:01:58 ]
HogeがPODじゃない場合はそもそもそういう初期化は出来ない

712 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 01:55:16 ]
>>707
この質問は>>700だぞ? 一行目でちゃんと「Cです」って言ってるじゃん。
>>703だけ見て」ってお前、>>703だけ見ること自体がヴォケなんだよw



713 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 07:12:50 ]
>>646
規格の 12.5 p5 で、解放されるメモリブロックのサイズが渡されると
定められている。
> When a delete-expression is executed, the selected deallocation function
> shall be called with the address of the block of storage to be reclaimed
> as its first argument and (if the two-parameter style is used) the size
> of the block as its second argument.

かなり古い VC についてはバグとして見つかっていたみたいだけど、
新しいのでも直ってないのかな?
ml.tietew.jp/cppll/cppll/thread_articles/5126

714 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 10:25:48 ]
結論、そのコードがCで、今後C++に転用する可能性を排除できるのならmemset()でもいいんでない?
そうでないなら、>708で。間違っても、一部のロートルの世迷言に釣られてmemcpy(hoge + i, & foo, sizeof(foo))なんてしないように。

715 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 10:53:37 ]
>>711
こういうことなんだが。

struct {
  union {
    void *p;
    void (*func)(void);
    float f;
    double d;
  } u;
} s = {0};


716 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 10:56:01 ]
>>715
今規格見た。最初のメンバが初期化されるんだな。

717 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 11:59:14 ]
unionを{0}で初期化してもいいけど
最初のメンバと違う型で参照したら処理系依存ってことか

718 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 12:47:56 ]
EUCで「。」の区切りを見つけるにはどうすればいいですか
文字コードは0xa1 0xa3です。
偶然にaaaa 0xa1、0xa3 bbbb となった場合が判断できないですが。

719 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 12:59:15 ]
>>718
探したい対象が文字列のように、EUCエンコードされていることが保証されているなら、
0xa1から遡って0x80以上のコードが偶数個連続していたらその0xa1が1バイト目。
遡るのが嫌なら、先頭から監視するしか。

720 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 13:02:24 ]
実行ファイルやDLLに画像など任意のバイナリデータを埋め込むにはどうするればいいんでしょうか?
今考えてるのは、unsigned char配列にデータを読み込んで0xXX, 0xYY, 0xZZ, ・・・のような形式で出力するプログラムを作り
コンパイル前に一度実行してdata.datに保存。利用者側は
unsigned char data[] =
{
#include "data.dat"
};
と書いて使う。という感じなんですが・・・

721 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 13:07:32 ]
>>719
トンクス

722 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 13:09:09 ]
>>720
windows限定なら、標準のリソースとして埋め込めばいいのでは。アイコンなど。



723 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 13:53:35 ]
>>719
文字化けや不要コードの埋め込みなどが原因と思うけど
いい具合に出来なかった。

724 名前:718 mailto:sage [2009/11/13(金) 14:05:36 ]
変換ツール任せでやってみる。wstring型に変換できれば比較は簡単だから。

725 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 14:21:20 ]
wchar_tに変換して出来ました。
手間かかるけど、文字化け多発するよりかは良いか。

726 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 15:47:40 ]
vs2008なのですがboostのshared_ptrでインテリセンスって使えますか?
試したところ効かなかったのですが

using boost::shared_ptr;
shared_ptr<Hoge> pHoge = shared_ptr<Hoge>( new Hoge( 3 ) );
pHoge->
↑で出したい

727 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 16:18:31 ]
std::tr1::shared_ptrなら出るよ。

728 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 16:45:12 ]
C++の識別子長すぎていらつく
スコープ付きの識別子の別名定義ができれば便利なのに


729 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 16:51:33 ]
つスコープ内でtypedef

730 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 16:52:48 ]
725だけど、「。」の発見は出来たけど、こんどは文字種の特定が困難になったよ。
かな、カナ、漢字など。UTF16らしいが文字コードがよくわからん。
EUC -> UTF16 -> SJIS OR EUCと何度も変換するしかないのか。

731 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 17:11:00 ]
>>727
試したけどダメっぽいです。コンパイルは通るんですが
何か根本的な間違いをしてるのかも・・・。
ひとまず諦めます

732 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 17:13:00 ]
>>729
それじゃ型限定じゃん
変数や関数の別名を参照や関数ポインタ使わずに楽に短くしたいんだよ




733 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 17:16:05 ]
>>731
インテリセンスするための情報収集が狂っちゃうと、そういうことがおきるねー

リビルドや
中間ファイル(.obj や .res .scc .pdb .pch .ilk .idb .ncb .plg .bsc まだあるかも)を完全に消してのビルドで
復活したりするよ。

734 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 17:40:31 ]
>>732
C#のusing的なやつ(しかもスコープ限定)が欲しいってことか。

735 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 18:07:55 ]
>>730
混ぜるな危険

736 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 18:18:15 ]
>>714
まぁ俺も sockaddr_in 辺りは memset でクリアしちゃ
うけどさ。

> そのコードがCで、今後C++に転用する可能性を排除で
> きるのならmemset()でもいいんでない?

厳しく言うと >>715 みたいなのは union を struct に
しても memset はアウトだよな?

737 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 19:05:49 ]
[迷信] とりあえず memset で初期化
www.kijineko.co.jp/tech/superstitions/initialization-by-memset.html

738 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 20:29:57 ]
>>737
リンク先あっているのか?
A a[10] = {0} で a[0]〜a[9] のすべてが0クリアされるのか?
static なら保障されているが、auto な配列ではダメなのでは?

739 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 20:30:49 ]
されるよ
ダメくない

740 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 20:44:04 ]
>>739
確認しました。
明示的に初期化される、ただし、一部しか明示されていない場合は、残りは 0 で初期化される、これは
auto でも static でも同じとのことですね。
thanks a lot.

741 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 23:45:42 ]
>>733
もしやと思ってSP1にアップデートしたらstd::tr1::shared_ptで出来ました!
今までアップデートしてなかったんだなぁ…

742 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 03:37:57 ]
sscanfでは、第一引数の文字列の
半角スペースのある領域を""で囲っても、
ひとつの区切りとしてくれないみたいですが、
それができる方法がありましたら教えてください。

sscanf("\"abc de\" 5", "%s%s", s1, s2);



743 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 03:39:42 ]
>>742
面倒でもstrtok()使え

744 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 03:46:13 ]
*scanf は糞

745 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 04:23:51 ]
>>743>>744
ありがとうございます。
やはり、自前で実装ですか・・
やってみます。

746 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 04:31:30 ]
parserつかえ

747 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 04:51:18 ]
>>746
ありがとうございます。
試してみます。

748 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 05:52:57 ]
>>742
"%s"ではなく、"\"[^\"]"を使えばOK!

749 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 07:21:31 ]
構造体の配列について質問です
構造体Aを
A **a
で定義し a[x][y] でメモリを確保して他の関数に引数として渡します
その際
test_func(**a)
test_func(*a[y])
test_func(a[][y])
で全て同じ定義だと思うのですが全て関数の中で
a[i][j]でアクセスできますよね
(ただし i <= x && j <= y)
二つ目と三つ目では[y]で定義しているのでアクセス可能かと思いますが
一つ目はどうやって認識しているのですか?

750 名前:デフォルトの名無しさん [2009/11/14(土) 07:23:15 ]
unsigned long からfloatに変換した場合、起こりうる問題を教えてください

751 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 07:38:56 ]
>>750
有効桁数が減ります

752 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 07:55:40 ]
>>749
アクセスの仕方は一緒でも
渡されるものの内容が違います



753 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 08:49:47 ]
>test_func(**a)
>test_func(*a[y])
>test_func(a[][y])
>で全て同じ定義だと思うのですが

ちがいます

754 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 09:51:11 ]
>>753
一つ目と二つ目は違いますが二つ目と三つ目はおなじですよね?
ポインタのポインタとして渡された先頭のアドレスが渡された関数で
アドレスしか渡してないのにその内部構造が定義したように認識されているのはなぜなのでしょうか?

755 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 09:54:11 ]
>>754
二番目と三番目で渡している型は
配列を指すポインタであって、ポインタのポインタではありません

756 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 09:58:06 ]
>>754
少なくとも2と3はまったく違う
1と2は一緒とみなしてよいときとそうではない場合がある

757 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 11:56:11 ]
>>748
ありがとうございます。
試してみます。

758 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 15:26:21 ]
CLASS x=y; は
xは初期化されず
コピーコンストラクタへいくね。
これってたまたま不定値によっては動作がおかしくなりそうだが。
メモリ確保してあるかどうかのフラグの部分でおかしな動作したよ。

759 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 16:03:10 ]
>>758
コピーコンストラクタは初期化処理の一種なわけだが。
CLASS の定義がバグってるんじゃね?

760 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 16:10:49 ]
CLASS () { flg=0; }やCLASS (int n) { flg=0; }だとflgは確定してるけど
コピーコンストラクタは、xが初めて生成されたのか不明で
初期化して良いのかわからないと思ったんです。
コピーコンストラクタは初期化時にしか使われないんですか。
代入と一緒の気がしてました。どちらの場合も対応しないといけない気がしてました。

761 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 16:13:36 ]
>>760
コンストラクタはぜんぶ初期化処理。
初期化後のコピーは代入演算子で定義する。

762 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 16:15:04 ]
トンクス!



763 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:12:15 ]
>749

>test_func(**a)
>test_func(*a[y])
>test_func(a[][y])

これはプロトタイプ宣言の話?
それとも呼び側?
それによって話が変わる。

プロトタイプ宣言ならNを正の整数定数として
1)void func(char **a);
2)void func(char *a[]);
3)void func(char a[][N]);
4)void func(char (*a)[N]);

1と2は全く同じ意味。3と4は全く同じ意味。

764 名前:763 mailto:sage [2009/11/14(土) 19:15:55 ]
>749

よく読むと A a[x][y];
を渡したいみたいだね。
それならば、>763の3か4を使う。
1,2ではダメ。


765 名前:763 mailto:sage [2009/11/14(土) 19:23:23 ]
>749

何度もすまん。

>A **a
>で定義し a[x][y] でメモリを確保して他の関数に引数として渡します

aの定義がA **aなら1か2で渡す必要があるが、
それと
>a[x][y] でメモリを確保して
という部分がつながらない。

やりたいことはこれ?
A hoge[x][y];
A (*a)[y] = hoge;

それともこれ?
A **a;
int i;
a = malloc(sizeof(A*)*x);
for (i = 0; i < x; i++) {
a[i] = malloc(sizeof(A) * y);
}


766 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:45:18 ]
Visual C++ 2005 の環境でファイルを出力するプログラムを作成していますが、
期待通りに出力が行えません。

fprintf_s関数の第2引数の中で、%sを指定していますが、
文字列ではなく、文字として、「C」だけが出力されているようです。
どのようにすれば、文字列「C:\test」が出力されるのか、お分かりの方がおりましたらご教授いただけませんか?

-----プログラム-----
CString csvFile = _T("C:\\test");
FILE *fileStream;
if(_tfopen_s(&fileStream, (LPCTSTR)csvFile, _T("w")) != 0)
{
return -1;
}

fprintf_s(fileStream, "あいうえおABC123\r\n"); // あいうえおABC123
fprintf_s(fileStream, "FILE %s\r\n", csvFile); // FILE C:\test → FILE C

-----出力結果-----
あいうえおABC123
FILE C

-----期待している出力結果-----
あいうえおABC123
FILE C:\test

※ファイル名を格納してる変数の型は、他の処理でも使用している都合上、変更できません。


767 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:52:03 ]
>>766
試してないけど、こうじゃない?
_ftprintf_s(fileStream, _T("FILE %s\r\n"), static_cast<LPCTSTR>(csvFile));

可変長引数に渡す場合にクラスからの暗黙の変換は効かない。
CString 使うなら TCHAR を扱うように統一しないと。
Cスタイルキャストは無しで。

768 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:52:15 ]
fprintf_sの引数を(LPCSTR)csvFileにしたらどうだろうか

769 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:54:38 ]
>>766
_T マクロ無しにしたら?

770 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:59:58 ]
>>767-768
大昔はともかく、いまのCStringはLPCTSTRとして扱ってもかまわないようにできてるから、
この場合問題なのはfprintf_sの"%s"にLPTSTRを渡してることだと思う。
つまりtprintf系の関数を使うのが正しい

>>769
それは間違ってる。むしろ至る所に_Tマクロを使うべき

771 名前:766 mailto:sage [2009/11/14(土) 20:09:45 ]
記載いただいた内容で出力することができました。
ありがとうございます。

>>767-770
C言語と比べると全然違うんですね。
Cを少しかじったことがあるので、書けると思っていたら全然でした…。


772 名前:766 mailto:sage [2009/11/14(土) 20:14:34 ]
>>770
770さんの書き込みをよくよく読むと出力はできるけど、
これだと正しくないということですか?



773 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:19:02 ]
ジェネリックテキスト(_Tマクロとか使うやつ)は使わないほうがいいだろ。
95/98対応する必要があるとかかわいそうな人なんてもう、そうそういない
だろうし、ワイド文字列きめうちのほうがトラブルがなくて楽だよ。

それにジェネリックテキスト使っていたって、本当にワイド文字列と
マルチバイト文字列の両方に対応できてるコード書けてるかってのもあるし。

両方で動くように意識して書いてるやつなんて少数派だし、_UNICODEありと
なしでコンパイルが通るかとか、テストを両方でやってるところとかまで
いくと壊滅状態だろうし、事実上ジェネリックテキストなんて機能してないよな。


774 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:21:28 ]
>>770
> 大昔はともかく、いまのCStringはLPCTSTRとして扱ってもかまわないようにできてるから、

へー。いまの可変長引数の ... 部分に渡したときも LPCTSTR への暗黙変換が入るのかー。
いったいどういう仕組みで?
クラスに operator LPCTSTR () を持ってるだけじゃ、そうはいかないよね?

775 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:25:03 ]
>>773
一般的な話ならそれでもいいんだけど、ここでは CString を使ってて、
その型は変えられないと質問者が言ってるんだから _T() が要るだろ。

776 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:25:58 ]
>>774
>>770じゃないけどCSimpleStringT<>のソースは大分前に見たよ

データメンバがポインタ1個でvtblもないから
メモリレイアウトがTCHAR*と同じになってるんだよ確か

777 名前:768 mailto:sage [2009/11/14(土) 20:29:40 ]
よく考えたらLPCSTRへ変換はできなかったかも
CStringへ代入はできるけど

778 名前:766 mailto:sage [2009/11/14(土) 20:31:31 ]
ごめんなさい。
出力はできるようにはなったのですが、日本語が含んでいるとクエスチョンマークの
文字列が並んでしまいます。
これはやっぱり、上で説明されている変換がうまくいっていないからですか?

779 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:32:44 ]
>>778
setlocale(LC_CTYPE, "");
とかやろう!

780 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:32:49 ]
>>770,776
msdn.microsoft.com/ja-jp/library/awkwbzyc.aspx#_core_using_cstring_objects_with_variable_argument_functions
> ... 可変個の引数リストを取る関数に CString オブジェクトを渡すときは、明示的に
> 型キャストによる変換を行う必要があります。

やっぱりダメじゃねーか。

www.trickpalace.net/cppll/reference/printf.htm#argument
こいつのデマに騙されたんじゃね?

781 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:37:51 ]
>>780
#include <cstdio>
#include <atlstr.h>

int main()
{
    CStringA s = "world";
    std::printf("hello, %s\n", s);
}
うちではこのコードはVC7.1でもVC9でも動くよ
まあ推奨はしないってか誰もしてないと思うけど

782 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:41:17 ]
>>780
古いATLの利用を考えているならキャストするのが安全だろうけど、
最近のはreinterpret_cast相当の操作でも安全に使えるようにできているから必要はない。

というのはATLの解説書のどれかに書いてあったはず



783 名前:766 mailto:sage [2009/11/14(土) 20:44:59 ]
>>779
無事に出力できました。ありがとうございます。
第2引数に何か入れた方が良いのかと思いましたら、そのままでも平気なんですね。

784 名前:781 mailto:sage [2009/11/14(土) 20:52:17 ]
どーでもいいけど例が良くなかったね

#include <cstdio>
#include <atlstr.h>

int main()
{
    CStringA s = "world";
    std::printf("hello, %s %d\n", s, 123);
}

これがちゃんと動きます。

785 名前:774 mailto:sage [2009/11/14(土) 21:08:10 ]
groups.google.com/group/microsoft.public.vc.mfc/browse_thread/thread/028f80f03d7e253d#msg_7fb2a35dbe1e6ff1
把握した。なるほど。

開発者はがんばって大丈夫なようにしたけど、外向けの仕様としてはキャストが必要と
書かれたままになってるってことだね。ちょっと不憫だな。まぁ古い実装を使ってる場合や
可変長引数の実装方法の違うコンパイラを使う場合にはやっぱり問題になるんで、
しょうがないところかとは思う。

>>780
デマじゃなかったみたいね。

786 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 21:12:38 ]
C++でポインタを *で参照はがしした時って、*pointerは参照ということになるの?
codepad.org/A8sFOqoG
こんな感じで仮想関数使いたい場合、とりあえず思った通りに動くんだけど、
*baseとした時点でBase型に補足されるということはないんですか。

787 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 21:14:29 ]
>>786 参照だよ。

788 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 21:17:35 ]
わかりました。ありがとうございます。

789 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 14:40:57 ]
char 配列が300個連続で0であることを高速で見つけるにはどうすればいいですか。

790 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 14:48:00 ]
どういう意味で高速なんだ

791 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 14:56:55 ]
CPUの性能を上げれば高速になるよ

792 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 15:11:29 ]
ひとつひとつ探すより、memcmp使うとかです。
これは実際に速くなるのですが、500個になると困ります。



793 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 15:12:39 ]
0に限定すれば、memcmpより高速に出来る可能性があると思いますが
アセンブラなどわかりません。

794 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 15:15:32 ]
O(n)よりは速くならないんだから、あとはCPUのデータシート眺めながらチューンしていくしかないよ

795 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 15:18:52 ]
いい方法わかりました。300個目だけ1だったら途中は調べなくて良かったです。

796 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 16:54:40 ]
ああもうそれでいいよ、もう来ないでね

797 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 23:16:34 ]
>>795
もう少しマシにしようか
300個が0なら150個目を調べる
それも0なら75個目と225個目を調べる
それも0なら・・・・

非0である確率が高いならともかく、そうでないなら最初から順々に調べたほうがマシだな

798 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 00:13:52 ]
>>797
えっ

799 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 00:20:58 ]
データに偏りがあるなら、そういう最適化もあるが、ないなら最初から配列舐めるなぁ。。。

800 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 00:22:43 ]
つまらないこと言ってないで、死の行進しとけよ
学生はIT土方になるために必死に勉強しとけ

801 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 01:54:58 ]
> これは実際に速くなるのですが、500個になると困ります
なんで?

そもそも memcmp() 呼び出しが 単純なループ処理より速いってどんな環境?
(つーか、まさか毎回if判定してないよな?)

802 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 01:56:41 ]
>801
いや普通、ループは毎回判定してるぞw



803 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 02:05:47 ]
例えば
・charではなく、もっと大きな(intとか)のサイズでアクセスし
・毎回判定するのではなく、数十個単位とかを|してから判定することにして
・さらに、場合によってはプリフェッチ的なアクセスの仕方も行う
というようなことをすれば、

・もしかしたら
・あなたの使っているCPUやOS、及びコンパイラと使用ライブラリ限定で
・データによっては
・気休め程度には
速くなる可能性はあるかもね。

804 名前:デフォルトの名無しさん [2009/11/16(月) 11:02:47 ]
バーチャルで関数をオーバーライドするときって型を変えたりできないんですか?
virtual ってvoidばっかりなのですが


805 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 13:34:53 ]
>>804
基本的にはできない。
例外として共変戻り値がある。

806 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 16:46:54 ]
グローバル変数はどこから書き換えられるか解らないといった弊害があるから推奨されないかと思うのですが
グローバルな定数であれば別にガツガツ使用しても問題ないのでしょうか?

807 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 16:57:15 ]
一番大事なことはそれではないとおもう。
変数がかぶることと思う。
ネームスペースやオブジェクト指向も
変数名、関数名がかぶらなくなることが大事思う。

808 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 16:59:04 ]
変数や関数の生存範囲が小さいほどよい。
公開する部分はのぞく。
グローバル定数も変数も公開するで無ければなるべく範囲を縮める。

809 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 17:02:19 ]
変数を生成するコストを減らすためとかいう理由で
グローバル使うのはあほですよ。
大して時間食わないし、変数生成がボトルネックなることはまれ。
時間食ってることが確認できてから変えれば良いんです。
なるべく生存範囲が短くなるようにするのが吉

810 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 17:02:27 ]
じゃネームスペースの中にグローバル変数入れときゃいいじゃん

811 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 17:07:16 ]
>>805
ありがとうごじあました

812 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 17:08:01 ]
名前の競合なんて屁でもないだろ。
モジュール間でのカプセル化という意味合いの方が大きい。



813 名前:806 mailto:sage [2009/11/16(月) 17:29:33 ]
グローバル定数も出来る限り控える方が良いんですね。
ありがとうございます。

814 名前:デフォルトの名無しさん [2009/11/16(月) 18:25:46 ]
error C2276: '&' : 仮想関数のアドレスを取ろうとしました。
とか、書き方を変えると、
error C2440: '<function-style-cast>' : 'overloaded-function' から 'float' に変換できません。
とか出ます、仮想関数をはじめていじくっているのでどうすれば良いかわかりません
仮想関数のオーバーライド中では引数のメンバの型を変えてはいけないのですか?

815 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 21:24:18 ]
>>814
スレ違い。↓こっち行け。
pc12.2ch.net/test/read.cgi/tech/1187922645/

816 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 21:59:01 ]
グローバルスコープがふさわしい物までグローバルから追い出そうとするのも問題だと
個人的には思う

つーか、初心者が一番やらかしやすいのは、関数スコープがふさわしい物をファイル
スコープに出してしまうことじゃないかと

817 名前:デフォルトの名無しさん [2009/11/16(月) 22:23:03 ]
vc++でトランプゲームとか作ろうと思っています。そこで質問が二つあります。
@画像データをPROJECT内に保管しておいて必要な部分を切り取って表示する方法ってありますか?
AWIN32とmfcとで方法が違うかもしれませんが、ゲームを作成するのに向いているのはどっちでしょうか?

※開発環境(といえるほどのレベルではないのですが・・・)VISUALSTUDIO2005でvista32bitです。
入門書とかも何冊か読んでみたのですが、自分が求めている情報がズバリ載っているわけではいないので、
質問させていただきました。詳しい方がいらしたらぜひアドバイス願います。


818 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 22:29:58 ]
>>817
1、ビットマップの管理方法で違う。APIに任せるなら、loadImageしてBitBltなどのAPIを使う。
  自前で管理するなら、配列いじるのと変わらない。が、約束事はある。
2、どっちでも作れるから、作りやすいほう選べ。CかC++か位の違いしかない。どっちにもお約束事はある。

819 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:09:48 ]
環境変数はグローバル変数だから使用禁止
外部からファイル読み込むのもグローバル変数だから使用禁止

820 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:17:27 ]
#define HOGE 1
#define HOGE 1
#define HOGE 1
#define HOGE 2
#define HOGE 1
#define HOGE 1

同じ名前の定数を何度も宣言した場合、値が同じうちは何も言われず、
上の場合は1→2と2→1のところでのみ警告が発生するのですが、
これはCやC++の標準の仕様として頼ってしまってもよいものですか?

Win32のDLLからエクスポートするクラス群が複数のヘッダに分散していて、
各ヘッダにそれぞれ
#ifdef HOGE_EXPORTS
#define HOGE_API __declspec(dllexport)
#else
#define HOGE_API __declspec(dllimport)
#endif
を入れてしまいたいのです。

それとも、上のものだけが書かれた二重インクルード対策付きヘッダも別に用意して、
各クラスのヘッダからちゃんとインクルードするべきですか?

821 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:19:43 ]
>>820
#ifndef HOGE_API
#ifdef HOGE_EXPORTS
#define HOGE_API __declspec(dllexport)
#else
#define HOGE_API __declspec(dllimport)
#endif
#endif

822 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:22:58 ]
>>820
同じ名前で内容の全く同じマクロなら何度定義してもいいことになってる。
(厳密にはもう少し複雑な規定があるけど)



823 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:46:26 ]
>>821-822
何度定義してもよいということが仕様として存在するのですね。
安心しました。ありがとうございます。

824 名前:デフォルトの名無しさん [2009/11/16(月) 23:49:24 ]
名前: デフォルトの名無しさん
E-mail:
内容:
818さんアドバイスありがとうございます。さっそく、プログラムに入力しビルドしてみました。私の力量不足でエラーになってしまいましたが、 loadImage()をいかに使いこなせるかというところが質問の答えのようですね。
A:秀和システムの本:「VisualC++.net逆引き大全」
B:秀和システムの本:「C言語逆引き大全」をぱらぱらとめくってみました。
AのほうにはMFCのところにLoadBitmapを使った方法が載っており、BのほうにはLoadImage()を使う方法が載っていました。

Aのほう
CBitmap m_hBitmap;
if (m_hBitmap.LoadBitmap(CARD)){
}
pDC->DrawState( CPoint(0,0),
CSize(100,100),
&m_hBitmap;
DST_BITMAP);

Bのほう
HANDLE LoadImage(
HINSTANCE hinst,//インスタンスのハンドル
LPCTSTR CARD,//イメージの名前または識別子
IMAGE_BITMAP,//イメージのタイプ
100,//希望する幅
100,//希望する高さ
LR_DEFAULT //ロードのオプション
);
という風なことが書いてあるのですが、Aのほうは、構文エラー )や;があるとかないとか。
Bのほうは、LR_DEFAULTが認識されない識別子だとか、 )や;があるとかないとか。
のエラーが出でしまいます。 これはなぜエラーになってしまうのでしょうか?
理由が分かる方、ぜひアドバイスをお願いいたします。※CARD.bmpという画像ファイルを扱おうとしています。

825 名前:デフォルトの名無しさん [2009/11/16(月) 23:54:46 ]
デバッグしてるときに変数に何が入ってるか知りたいのですが_CrtSetBreakAlloc(1162);これしかないですか?

826 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:55:49 ]
>>825 VC ならデバッガ使えよ。

827 名前:デフォルトの名無しさん [2009/11/16(月) 23:59:30 ]
>>826
効果的な使い方がわからん
_CrtSetBreakAlloc(1162);で止めて下に出てるツリーを開いていくやり方以外やったことない
教えて

828 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 00:07:56 ]
>>827
_CrtSetBreakAlloc()って知らんからググってみたら、メモリリークの箇所を
調べるみたいなことが書いてあった。
勉強になるなぁ。

変数の中身をみるって、適当にブレイクポイントでとめて、ウオッチで見るとかじゃなくて?

829 名前:デフォルトの名無しさん [2009/11/17(火) 00:10:22 ]
おkサンクス、やってみる

830 名前:デフォルトの名無しさん [2009/11/17(火) 00:13:03 ]
ああ、普通こうやってやるのか
すげえな、サンクス

831 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 05:38:13 ]
VCならウォッチ式の設定とか言わず、変数をポイントするだけでもおk。

832 名前:デフォルトの名無しさん [2009/11/17(火) 06:05:27 ]
ちょwwVC便利すぎワロタw
プログラム暦2年だけど何やってたんだ俺wめっちゃ簡単に割り出せるやんw



833 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 06:32:32 ]
vectorの内部で確保されているメモリってclear()でも解放されるの?

834 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 06:36:33 ]
解放されない

swapですれよ

835 名前:833 mailto:sage [2009/11/17(火) 06:47:54 ]
なるほど、どうも

836 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 07:26:26 ]
std::vector<T> v のバッファサイズをバイト単位で取得したい時は、
v.size() * sizeof(T)
でいいんでしょうか?
実装によっては何か詰め物でも入っているのではないかと不安なんですが。

837 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 07:40:57 ]
vectorのバッファは配列と同じメモリ配置であることが保証されてるから、それでいいよ

838 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 07:54:16 ]
>>836
そのサイズを使った操作が何であるかによっては危険な予感がする。

839 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 08:22:29 ]
>>837
ありがとうございます。
>>838
内容をファイルに書き出したいんです。

840 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 15:26:13 ]
普通に書き込めばいいじゃん

841 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 17:07:07 ]
>>839
ostreamのシフト演算子を定義すればいいと思うよ。
v.size() * sizeof(T) だと、vtableがあったら色々まずい。

842 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 17:21:33 ]
バッファサイズに仮想関数テーブルは関係ないだろ



843 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 17:42:42 ]
copy(v.begin(), v.end(), ostream_iterator<T>(cout, "\t");

これってさ、Tによっては<<定義しても動作しなくね?

844 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 00:58:34 ]
>>843 Tによらずコンパイルエラーになるね。

845 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 01:16:44 ]
>>844
いやそういう下らん揚げ足取りはいいから

846 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 01:20:59 ]
>>843
動作しそうで動作しない T の例をひとつでも挙げてみてくれ。
そうじゃないと、当たり前のことを聞かれてるだけにしか見えん。

847 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 17:25:58 ]
メモリイメージをメモリマップトファイルにmemcpyすれば楽ちん。
ていう考えは古いですか。

848 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 19:48:32 ]
質問させてください。
静的メンバはクラスが存在する前からあるはずなのに、なんでクラスの外で再宣言しなくてはならないんですか?

849 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 20:19:01 ]
ヘッダファイルにクラス定義を書いた場合ということでいいのかな?

その場合、各翻訳単位の間で重複してクラスの静的変数を定義しない為。
ヘッダファイルにグローバル変数を書いて共有するときも、externで宣言しといてどこかで一度だけ実体の宣言をするよね。

850 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 21:00:32 ]
codepad.org/auJS2ura

ngの部分でコンパイルエラーが出てしまいます
VC++2008EEのエラーメッセージによると引数があいまいだから、ということなんですが
どうすれば曖昧さをなくせるのかちょっとわかりません
うまいことstd::endlを渡す方法はありませんか?

851 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 21:40:11 ]
>>850
endlの型を調べよう

852 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 21:48:59 ]
CParent ◇- CChild

というように親クラスが子クラスを保持しているとします。

子クラスはプログラム動作中、たくさんnewでメモリを確保します。

プログラム終了時、CChild内でdeleteせず、CParentでだけdeleteすれば、
CChildがそれまで確保してきた領域も伴ってdeleteされるのでしょうか?


というのも、ある書籍についてたサンプルコードを見ると、newしまくりなのに、
それらがdeleteされる記述がぜんぜんないんです・・・
最も最上位のクラス(他の下位クラスを保持している)を最後にdeleteしてるところ
くらいしか考えられない・・・


よろしくお願いします。 m(_ _)m



853 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 21:51:28 ]
メモリリークしちゃうね
とりあえずその書籍の名前を


854 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 21:56:05 ]
スマートポインタ使ってたらそう見えるかもしれない

855 名前:852 mailto:sage [2009/11/18(水) 22:01:00 ]
>>853
「3D格闘ゲームプログラミング」という本です。
不思議なことに、サンプルのVC++プログクトでビルド実行してプログラムを終了させたとき、
リークがある場合にVC++のログ出力に出てくるメモリリークバイト数が出て来ず、
正常終了できたかに見えます・・・

>>854
スマートポインタを使っているようにも見えません・・・

一例として

ヘッダファイル内
char* xxx

C++ファイル内
 xxx = new char[ strlen( yyy ) + 1 ];

で、xxxはどこでもdeleteされていません。
VC++上でソリューション内を検索もしましたが見つかりませんでした・・・

856 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 22:09:26 ]
別の変数に代入されてどっかで解放されてるんじゃないの

857 名前:852 mailto:sage [2009/11/18(水) 22:21:50 ]
>>856
追跡してみましたが、見当たらず・・・

そういえば、newされたやつの多くはSTLのvectorにpush_back()されています。


ヘッダーファイル内
 #include <vector>
 using namespace std;

 vector<CChild*> Child;

C++ファイル内
 Child.push_back( new CChild() );


何か関係があるのでしょうか?
このvectorはポインタのコンテナになっていて、やはりどこかでそれらのポインタの先にある
実体領域を解放してやる必要がありますよね?

858 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 22:24:30 ]
そういわれても実際にコードを見られないんじゃ何とも答えられん。

859 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 22:26:10 ]
Childが死ぬときに開放してるんだろ。
とりあえずステップ実行して、本当に開放されないのか一行ずつ確認してください。

860 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 23:01:08 ]
>>848
クラスの外に書くのは、宣言ではなく定義。

861 名前:852 mailto:sage [2009/11/18(水) 23:01:49 ]
作者さんのページで、どうも関係のありそうな記述を発見しました。

ttp://cgi32.plala.or.jp/higpen/book/shtPro/qa.shtml#program10

違う書籍の違うプログラム部のところの話ですが、
たぶん、これと同じことだと思います。

なんと、解放はOSに任せられるとのこと。
あまり行儀は良くないですよね^^;
よほどプログラムの動きやOSのメモリ管理に精通してないととてもできないw

でも勉強になりました。

みなさん、ありがとうございました。 m(_ _)m

862 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 23:19:45 ]
なんか苦しい言い訳に見えるな。百歩譲ってそれが「正しい」方法だとして、
プログラミングを勉強する本にそういう書き方をするのはいかがなものだろうか…



863 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 23:26:33 ]
質問を勝手に自分の理解できる範囲の問題に解釈し直すのはいくない

864 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 00:25:35 ]
>>861
そんなこと言ってると、ごちゃごちゃ言ってないで std::vector 使えカス、ってバカにされちゃうよ。

865 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 00:29:15 ]
VC6 時代の古い本ならしょうがないか、と思ったけどそのリンク先 Q&A の
日付見たらごく最近なのな。著者が不勉強なんだろうと思う。

866 名前:852 mailto:sage [2009/11/19(木) 00:57:36 ]
>>864
多態を使わなければ、クラスのインスタンスのvectorを使ってもOKみたいですね。


vector<CXXX> xxx;

CXXX x;

xxx.push_back( x ); // xxxコンテナへのコピーになる


これだったら、領域確保はvectorがしてくれるので楽ちんですね。

これでいきます。
ありがとうございました。

867 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 01:51:30 ]
コンストラクタ初期化子を使わないと駄目だっていうけど、初期化の順番を明示したい場合はコンストラクタ関数内で初期化してもいいよね?俺悪くないよね?



868 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 01:53:45 ]
どうでもいい。

869 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 02:41:35 ]
>>867
IDE のインテリジェンス機能が動かなくてもいいならそれでもいいよ

870 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 02:57:34 ]
コンパイル時にクラスや構造体のメンバのオフセットアドレスを得る方法ってあります?

871 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 03:00:38 ]
offsetof

872 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 03:30:02 ]
>>871
それだったか、感謝。



873 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 08:16:43 ]
>>861
それはメモリリークそのものだろw
そんなレベルで本書くなよ…

874 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 08:47:42 ]
よく読んでないけど

説明は下手糞だけど、最初に確保したメモリをプールしておいて使いまわす手法じゃないの?
だとしたら、そういうのはリークとは呼ばないよ。
MoreEffectiveC++にもちゃんと書いてあるし。

違ったらごめんな。

875 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 08:48:47 ]
×使いまわす手法
○使いまわして、最後まで(プログラムのコード内では)解放しない手法

876 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 08:57:25 ]
メモリなら最悪リークしてても、プロセス終了時に解放されますよって話だろ?
まぁメモリ以外のリソースだと解放してくれなかったりすることもあるけど。

877 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 09:29:20 ]
だから、たとえ解放処理(free/delete)をしていないとしても
ちゃんと管理できているものは「リーク」とは呼ばないって話だよ。

878 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 09:34:03 ]
>>867
初期化の順番はメンバの宣言順と決まっている。
コンストラクタの記述方法で明示などできない。

無知なオマエ悪い。

879 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 09:38:59 ]
>>874-875
よく読んでみなよ。 >>861 のやつは使いまわしてすらいない。

880 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 09:39:33 ]
最後にOS任せで消滅させて、途中どんなに肥大してもシラネ、ってのは管理ではなく
リークと呼ぶだろw

881 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 10:06:29 ]
>>879
だから、
>タスク用メモリはプログラムの終了時まで解放しない
が、「deleteを呼ばない」という意味ではなく
「プログラム終了まで使用している領域である」という意味ではないか、と言っている。
使用している(管理している)領域なんだから、deleteするコードが無くても問題ない。

もちろん、その「タスク」が、プログラムの中で際限なく増えていく
(あるいそのタスクを指す領域を見失っている)ようなら問題だが
俺はコードを読んでないので、どういう構造なのかは明言できない。


だから、「よく読んでないが」「説明は下手糞」と書いた。
そして、(明示的にdeleteを呼んで無くても)管理下にあるものはリークとは呼ばない。これは確実。

882 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 10:07:54 ]
で、使いまわしているかどうかは問題の本質じゃない。
管理下にあるかどうかが本質。



883 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 10:23:05 ]
>>881-882
よく読んでみなよ。 >>861 のやつは管理下にすらない。

「タスク」じゃなくて char 配列のほうな。ローカルな生ポインタ変数に入れて、
そのままスコープアウトしちゃってるみたい。

当たり前の主張を長文で繰り返す前に、「よく読んでない」と自分でわかってる
なら元記事をよく読めと。

884 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 10:36:43 ]

このサンプルでは以下の理由から、new char[]で確保した領域を明示的に解放する処理を省略しています。同様の理由で、他にもメモリの破棄を省略している部分があります。

* サンプルプログラムをなるべくシンプルにしたい
* タスク用メモリはプログラムの終了時まで解放しない
* プログラム終了時にはOSがプログラムに関連するメモリを解放してくれる
* 一般にdeleteで解放したメモリはOSには返却されず、プログラムの内部に保持されたままとなるため、タスクリストの場合は実行中に解放する意味が薄い

上記の理由から、メモリを解放しなくても動作に問題はなく、他のプログラムへの影響もありません。推奨される方法としては、例えばタスクリストのデストラクタ
~CTaskList() を記述して、その中で上記のバッファを、
delete [] buf; のように解放します。この場合、bufをメンバ変数にしておく必要もあります。

885 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 10:49:18 ]
「禁無断転載」と明記された記事を意味もなく転載するのはおすすめしない。
せめて引用の形にとどめておけ。

886 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 12:04:53 ]
っていうか、いかなる場合でも
確保したメモリちゃんと解放すればいいんだよ。

メモリを解放するデメリットなんてないだろ?
もし、終了時に遅くなるとかいう話なら
「終了処理を速くするテクニック」として使えばいいだけの話。
それが必要になるときがくれば使え

887 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 12:08:20 ]
>deleteで解放したメモリはOSには返却されず、プログラムの内部に保持されたままとなるため、
再利用されるとか考えないのかね?

888 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 12:13:50 ]
その機構部分は仮に良い という立場だったとして
new と delete がペアになっていない構造だから

別コードで本当にリークさせてる部分の追跡をするのに面倒じゃね?

889 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 13:33:47 ]
deleteしてもメモリ返せないの?なんで?じゃあどうすんの?

890 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 13:34:17 ]
どうもしない

891 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 14:50:59 ]
なんで、サンプルで手抜きをするのかねぇ?
deleteなんて一行増えるだけじゃん。

いちいち言い訳を書くよりも
deleteを書けばいいじゃんか。

892 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 14:52:56 ]
deleteしてもメモリ返せないの?なんで?じゃあどうすんの?



893 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 15:02:56 ]
>>892
マジレスはしてあげないよw

894 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 15:03:31 ]
どうもしない

newしたときに再利用されるだろうな

895 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 15:34:47 ]
サンプルをシンプルにしたいからって理由で無茶すんなよなぁw
リーク検出とか使えなくなりそうだしなぁ

896 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 16:12:06 ]
>>893
無知は黙ってろハゲ

897 名前:852 mailto:sage [2009/11/19(木) 19:05:22 ]
物議を醸していますね^^;
作者の方は東大を出ておられますが、地頭が良いとこういう考え方になるのでしょうか・・・
ともあれ、今はnew、deleteはセットで書くよう心がけたいですね。

898 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 19:44:29 ]
deleteするしないはコードの本質でないと判断したんだろう。
まぁ論文ならそれでいいんだろうが、一般向け、しかも初心者が食いつきやすいゲームプログラミングの書籍で
それをやると何も考えずに模倣する馬鹿が出てきてしまうから、やめた方がいいと思うがな。

899 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 19:46:38 ]
メモリリークしてたらだめだ
実測しむ

900 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 19:49:53 ]
1Mのメモリーリークが100回起これば100M消費する
プログラムが終了すればOSが回収するが、
動いている間はそのまま。

901 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 21:10:32 ]
東大出てても糞コード書く奴はどうしようもないよ
しかも学歴が高いせいで自信だけはあるから逆にめんどい

902 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 21:34:57 ]
Cなら終了時まで解放しないメモリをfreeしないっていう層は結構いるから
その亜流なんだろう



903 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 22:48:47 ]
>>897
もちろんnew/deleteをセットで書いてもいいが
それよりスマートポインタを使うんだ

904 名前:852 mailto:sage [2009/11/19(木) 23:01:20 ]
>>903
COMでCComPtrを使ったことがあって、めちゃくちゃ便利でした。
自前のを作るとなると・・・うまく組めるかちょっと心配です(汗)
でも便利なのはたしかなので、勉強してみます。
ありがとうございます。

905 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 23:04:08 ]
shared_ptr < ・・・

906 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 23:36:09 ]
BCB5+Win環境です
char配列などを頻繁にnew・deleatする際、どっかのサイトで
win環境では固定サイズでnewしたほうが断片化しにくいと
書いてあったような気がするのですか
本当でしょうか?
あまりnewをいじりたくないので気になります

907 名前:852 mailto:sage [2009/11/19(木) 23:45:36 ]
>>905
おおお!
こんな便利なものがあったのですか!
VC++2008ならstd::で使えるそうですが、自分は2005ですね・・・
しかし、boostを導入すれば使えますね。
CComPtrと同じように使えるのであれば、慣れていますし、導入もし易そうです。

教えてくださって、ありがとうございました!

908 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 23:54:42 ]
std::multimap<int, int> test;
test[0] = 1
test[0] = 2
test[0] = 3
...いろいろ代入...

としたときに、
std::multimap<int, int>::iteartor begin = test.lower_bound(0);
std::multimap<int, int>::iteartor end = test.lower_bound(0);
std::multimap<int, int>::iteartor it;
for (it=begin; it!=end; ++it) printf("%d", it->second);

で得られる結果は必ず 1, 2, 3 の順番になると保障されていますか?


909 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 23:56:21 ]
std::multimap<int, int>::iteartor end = test.upper_bound(0);
でしたすみません

910 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 00:10:27 ]
されてません。

911 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 01:05:18 ]
>>906
new の回数を減らせば断片が減る(断片化しにくい)のはあたりまえ。

それ以前に、ほんとうに断片化による悪影響で困ってるのか?
Windows 上では、特にギガバイト単位のメモリ空間(アドレス空間)があたりまえな
最近の一般的な環境ではかなり稀なケースになると思うんだが。

912 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:12:17 ]
>>901
実際に動作させるコードでdeleteするしないの問題と、解説書でdeleteを省略するしないの問題を
区別できていないお前は多分低学歴なんだろうな



913 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:13:44 ]
実際に動作させるコードからかけ離れたコードを提示する解説書がそもそも問題
削っていい部分とそうでない部分があるが、こういうのを削っていいと思うようなら
糞コードと言われても仕方ない

914 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:15:13 ]
ま、万人向けの本でやっちゃだめだよな。

915 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:17:50 ]
ぶっちゃけこんなアホなコードを本気で擁護する奴なんて本人以外いるの?w

916 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:28:12 ]
>>912
省略したほうがシンプルでいいと思ったけど結局は言い訳がましい Q&A を書くハメに
なったってことで、解説書のための判断としても失敗だろ。

紙面の問題を考えても、 std::vector 使っとけば #include が1行増えるかもしれないって
程度だし。

917 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:38:29 ]
まぁ、全てを綺麗に書くことが正義という言語でもないし、本当に必要ならば手を汚す
こともあるけどな。>>884は手を染める理由としては全く不足だと思うが。
とりあえず買っちゃいけない類の本ではあるな。良い初心者は混乱し、悪い初心者は
汚れる。中級者以上なら他に投資すべき本があるだろう。

918 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 03:10:28 ]
確保したハンドルやリソースを開放しないままプログラムが終了しても
言語やOSの仕様でプログラム終了時に確実に回収することがわかっていて
かつ、リークしないこともわかっているなら、別に開放しないまま終わってもいいじゃないか。^^
たとえば、

int main() {
int* i = new int;
}

上のプログラムはメモリリークしていない。
なぜなら、ポインタが消失して削除不能になるのはプログラムが終了する瞬間であり
その直後にはすべてのリソースが回収されることが仕様で決まっているからだ^−^
美学とかいうなら別だが。


919 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 03:28:08 ]
classのお作法を守ってないからでしょ。後で書いた方?は直してるみたいだし

920 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 03:37:02 ]
あえてdeleteしない、なんて初心者向け解説本でやるべきじゃないよな。

「3D格闘ゲーム」ってことだから、おそらくキャラクタ2体分のオブジェクトを作って
プログラム終了まで開放しない、みたいなコードだと思うんだけど、
読者がそこから拡張していこうとした途端にメモリリークを起こす気がする。

921 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 06:08:35 ]
繰り返しのnewがでたらやばいんだって。

922 名前:852 mailto:sage [2009/11/20(金) 08:12:39 ]
この本はdelete問題の他にも、ちょっと「?」というか、もっと効率的な方法があるのでは?と
思ってしまうようなところもあるのですが、
アニメーション付Xファイルの読み込み、およびそれをゲーム中でアニメーションさせるところの
解説はものすごく参考になっています。
今までいくつかのWebサイトでそれを解説しているところも見てきましたが、
この本の内容が一番分かり易かったです。

アニメーションのための本質的なところ(動作、仕様レベル)だけ抽出して、
実装に向けたクラス設計や仕様は自分で改めて考えてからコーディングしていったら良いと思いました。



923 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 09:00:43 ]
分かりやすいように見えても、どこに罠が仕込まれてるか分からんのではなぁ

924 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 09:06:43 ]
糞コードを本にして売るほうも、本に書いてあるコードを吟味せずにそのまま使うほうもアホ

925 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 09:12:37 ]
Amazonレビューを見たら、そのアニメーションの解説も参考にするとまずそうな
雰囲気に見えるが…
まぁ、買っちまったら何とか活用したいんだろうけどなぁ…

つーかサンプルプログラムの作り方もひどそうだ
ゲームがコマンドライン引数でviewerに変わるらしいが、やってみたくてやっちゃった
のかな、使い勝手とか全然考えずにw
もちろん「コマンドラインの処理サンプルを入れたかったので」とか言い訳はいくら
でも思いつくが

926 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 10:25:39 ]
DLLとEXEでは使ってるアドレス空間が違うとのことなんですがポインタがどっちのアドレス空間に属しているかしらべる方法はありますか?

927 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 11:15:06 ]
>>918
そういう特殊な事例でしか当てはまらないものは
特殊な例としてあげればいいんだよ。

int foo() {
int* i = new int;
}
関数名を変えただけで、この処理はリークしているかもしれない。

int main() {
MyClass* i = new MyClass;
}
クラス名を変えただけだが、delete時にファイル削除とかしているかもしれない。

な? コードは修正されるもの。
そういうときに自分で罠を仕掛けてどうする。

928 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 11:33:29 ]
>>926
できるでしょうね

929 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 11:44:16 ]
連続稼働させるものや、多くメモリ確保する物では
メモリリークは致命的。
512K確保する関数を200回呼び出せば、合計で1ギガ消費する。
deleteしないでこれを放置するやつは超初心者

930 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 11:45:57 ]
ブラウザはよくリークする

931 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 13:23:01 ]
>>918
それはメモリリークだよ。
もう使わないからdeleteしていいのにdeleteしないままプロセス終了を迎えたら、それはメモリリーク。

「プロセス終了時に把握できているメモリリークがあっても特に問題無い」には反論しないけど、
「リークじゃない」はおかしい。

そのプログラムがメモリリークしてないなら、メモリリークしてるプログラムなんてこの世に無いよ。

932 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 13:44:20 ]
目立ってメモリリークしなければ無視でも良いけどね。
たとえば、4バイトのメモリリークで128M=2^24バイトたまるには、
400万回やらないといけない。
10秒に一回起こったとしても、400万回するには一年半ほどかかる。、



933 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 14:14:47 ]
まぁ、習慣的にリーク対策しないと、大事なとき忘れるし、コードの再利用したときも不具合を生みやすい。
俺は基本的にnewしないでスタックに確保するから、そういう問題はほとんどないな。
はやくスマートポインタが使いたいぜ。

934 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 14:18:40 ]
vcでメモリリーク検出できるからそれでいいよ。
わずかに残ったとしても致命的にはなりにくい。
なったら変更すればいいし。

935 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 14:25:54 ]
シングルトンな奴は基本 delete しねぇなぁ、俺は。

936 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:10:46 ]
new deleteはコンパイラ依存していますか?
別のコンパイラで確保したメモリを、VCでdeleteは出来ませんか?

937 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:27:03 ]
>>936
別のコンパイラどころか、同じコンパイラでも異なるDLLでnewしたオブジェクトをdeleteすることは
原則としてできません。(MFCの拡張DLLは別)


938 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:34:39 ]
new deleteはオーバーロードだってできるからな。
あえてやるひとはいないだろうけど、
自分以外誰にも使えないnewの実装だってありえる。

939 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:37:30 ]
そうだったんですか。
そうだとすると、DLLがメモリ確保してリターンしたら解放不可能になるんですか。

940 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:40:48 ]
んなこたーない
メモリを確保する関数 と 確保したメモリを開放する関数 を用意しときゃよい

fopen() と fclose() の関係

941 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:49:42 ]
DLL が提供しているのが newしたポインタを戻すだけで
その後始末の delete は呼び出し側がやってね  という造りはマズイ ってこと

DLL は 自前newしたものを戻すつもりなら それを受けて delete する部分も提供すべき

# で、後者を記述するのに安全を見て >>926 で保険かけたいんだけど… どうすれば良い?
# という流れになるのかな?

942 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:50:14 ]
Windows APIだとCreateなんたらでハンドル作ったら、
CloseHandleよびだしたりするね。



943 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:55:17 ]
----DLL----
typedef void *(*dll_alloc_t)(void *(*)(size_t), size_t);

__declspec(dllexport) void *dll_alloc(void *(*)(size_t), size_t);

void *dll_alloc(void *(*alloc)(size_t), size_t s)
{
     return alloc(s);
}

----EXE----
dll_alloc_t dll_alloc = (dll_alloc_t)GetProcAddres(hDLL, "dll_alloc");

void *p = dll_alloc(malloc, size);


こうした場合メモリはどっちに確保されるの?


944 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 16:03:32 ]
内部実装に詳しいわけじゃないから適当にいうけど、
EXEから呼ばれるDLLがリンクしているalloc関数を実装しているライブラリ・・・が
OSにメモリ割り当てを要求して、OSが返してくれる適当なメモリ領域・・・・の
一部分をallocが適当に調節して返すんだから、
どっかOSが適当に決めた場所なんじゃないの?

945 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 16:37:27 ]
VC++だとこうなったが・・・

//DLL.c
#include <stddef.h>

__declspec(dllexport) void *dll_alloc(void *(*alloc)(size_t), size_t size) { return alloc(size); }

//Main.c
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef void *(*dll_alloc_t)(void *(*)(size_t), size_t);

int main(void)
{
HINSTANCE hDLL = LoadLibrary("DLL");
dll_alloc_t dll_alloc = (dll_alloc_t)GetProcAddress(hDLL, "dll_alloc");
char *p = (char *)dll_alloc(malloc, 10);

strcpy(p, "hello!"); puts(p); FreeLibrary(hDLL); puts(p); free(p); puts(p);

return 0;
}

//OUT
hello!
hello!
ンンンンンンンンンンンンンンンン-


946 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 17:01:03 ]
これで良いみたいだな。winapi使った

// DLL

#include <windows.h>
#include <stdio.h>

extern "C" WINAPI void memo( HANDLE hd, char *&p ) {
p = (char*) HeapAlloc(hd, HEAP_ZERO_MEMORY, 1<<20);
strcpy(p,"hgujyguyguyguyguby");
printf("%s\n",p); }


// EXE

#include <windows.h>
#include <stdio.h>

typedef void (WINAPI *FNC)(HANDLE , char*& );
int main(){
HINSTANCE hd= LoadLibrary("dll.dll");
FNC memo = (FNC)GetProcAddress(hd, "memo");
HANDLE hHeap = HeapCreate(NULL, 0, 0);
char *p;
memo(hHeap, p);
printf("%s\n",p);
HeapFree(hHeap, NULL, p);
HeapDestroy(hHeap);
getchar(); }

947 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 17:48:12 ]
C言語でWin32APIをさわっています。winbase.hに
WINBASEAPI VOID WINAPI OutputDebugStringA(__in LPCSTR lpOutputString);

と書いてあったんですが__inって何ですか?

948 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 17:53:49 ]
msdn.microsoft.com/en-us/library/aa383701(VS.85).aspx
まずは自分で調べてほしい。

949 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 18:38:48 ]
DLLとメモリのやりとりを確実にするには、(HANDLE, char*)のペアで
扱うのが良いと思いますが、
一方ではペアとして、一方ではchar*と自動的にキャストさせる方法はありますか。

950 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 18:43:12 ]
>>948
縛りの弱いconstのようなものでしょうか?
SAL解釈と言うんですね
ググったんですがなかなかそこまでたどり着けませんでした

951 名前:949 mailto:sage [2009/11/20(金) 18:43:43 ]
自作関数だと、ペアでもchar*でも受け入れるように出来ますけど
自作ではない関数に対しても、自動でキャストして通るように出来れば便利なんですが。

952 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 18:46:22 ]
何でもかんでも暗黙キャストしてると後ですごい不安になる




953 名前:950 mailto:sage [2009/11/20(金) 18:46:57 ]
>SAL解釈と言うんですね
SAL注釈ですね、間違えました

954 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 18:47:31 ]
double - int みたいな暗黙キャストを実現する方法はないですか?

955 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 19:00:34 ]
>>949
ごめん、なんでハンドルが出て来るのか分からない。

956 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 19:05:55 ]
>>946

HANDLE hHeap = HeapCreate(NULL, 0, 0); と char *p; のペアを 
char*型のように扱いたいって事なんです。
無理でしょうか?

957 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 19:33:10 ]
std::vector< boost::shared_ptr< T > > と boost::ptr_vector< T > はどちらを使っても同じでしょうか?
「一方ではこれができないから注意!」とかあったら教えてください m(_ _)m

958 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 19:45:50 ]
猿介錯

959 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 19:52:27 ]
よくわからないならvector<shared_ptr<T>>のほう使っとけ

960 名前:957 mailto:sage [2009/11/20(金) 20:33:38 ]
>>959
分かりました!
ありがとうございます!

961 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 20:43:50 ]
shared_ptrって余分に一回メモリ確保してない?あれは何なの?


962 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 21:00:30 ]
参照回数を共有するため、その変数を確保してる。



963 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 21:00:34 ]
関数の戻り値は、通常 値渡しですが
100Mほどのデータをもつクラスでも値渡しになりますか。
(値渡しのコストを下げるために) もし100Mがポインタに入っていて、
auto変数でリターンするとデストラクタが働いてメモリは解放されてしまいますが
newで確保した物をリターンすると、それは解放できなくなりますか。

964 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 21:03:27 ]
戻り値にクラスを持ってこずに引数を参照渡しにすればいいのですが
変数を用意する事無しに、リターンがクラスになっていると便利なことがあるんです。

965 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 21:27:13 ]
戻り値がクラスというのは意味不明。

オブジェクトを返すとして、たとえば、
 LARGE func() { return * new LARGE; }
というのは結局コピーしてるし、メモリが回収不能になるので、絶対にだめ。

LARGE & func( LARGE & inout ) {
 //LARGEを使った処理。
 return inout;
}
として、外で大きなデータを用意してやるか、
funcで全く新しいオブジェクトを作成したいと言うなら、newしてポインタを返せばよい。

966 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 21:38:14 ]
>>965
Qtでこんな関数をオーバーロードしろって言われてるんだけど、
何を返せばいいの?

QSize sizeHint(引数略)
{
  return ?
}

967 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:05:09 ]
QSizeオブジェクトでいいと思うよ。

968 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:16:32 ]
え? でも>>965・・・

969 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:18:16 ]
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const

あとこんなのもあるんですが・・・


970 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:20:50 ]
QSizeオブジェクトを返すことが、ライブラリによって強制されてるんだから、従えよ。

971 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:21:12 ]
お前が何を聞きたいのかわからない

972 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:23:15 ]
> というのは結局コピーしてるし、メモリが回収不能になるので、絶対にだめ。
ってかいてるじゃないですか




973 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:23:59 ]
QSizeって大きくないでしょ。(というか100Mというサイズはどこから)
値で返しても何も問題ないじゃん。

974 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:40:44 ]
それ以前に

QSize sizeHint(引数略)

をオーバーロードするのに、
戻り値を参照やポインタにはできんだろ。
オーバーロードのルールを思い出すのだ。

975 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:42:16 ]
いや、戻り値を変えられないのはオーバーライドじゃろ。

976 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:47:28 ]
たまにいるよね(値|参照)(返し|渡し)の違いがわからない人って
まあわからないようなレベルでできることなんて高が知れてるから分かるまで値返しでいいんじゃないかな

977 名前:デフォルトの名無しさん [2009/11/21(土) 05:12:37 ]
インテルコンパイラでコンパイルしている場合に#ifdef分岐させたい場合、
#ifdefの後何を書けばよいのでしょうか?

978 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 05:16:39 ]
defined (__ICC)

979 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 05:35:04 ]
archives.postgresql.org/pgsql-committers/2007-08/msg00120.php

Apparently icc doesn't always define __ICC, and it's more correct to
check for __INTEL_COMPILER.  Per report from Dirk Tilger.
Not back-patched since I don't fully trust it yet ...


980 名前:デフォルトの名無しさん [2009/11/21(土) 05:37:04 ]
オンラインで見られて、プログラム未経験者向けのC++の講座って、ロベール以外に何がありますか?

981 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 09:58:59 ]
>>980
こことか見てた
Programing Place
ttp://www.geocities.jp/ky_webid/index_old.html


982 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 12:57:09 ]
ロベールの翻訳は分かりやすい



983 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 13:17:19 ]
>>982
どこが翻訳なんですか?

984 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 16:38:20 ]
自作クラスをcoutで出力するにはどうすれば良いですか?

985 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 16:41:43 ]
ここみたら無理そうなことがわかりました
諦めました
www.jah.ne.jp/~naoyuki/Writings/ExtIos.html

986 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 17:00:01 ]
そのページに書いてあるのは標準ストリームクラスの拡張であって、
君がやりたいのは標準ストリームクラスで自作クラスを出力することでしょ?
まったくの別件だと思うよ。

君が勉強すべきなのは、演算子オーバーロード。

987 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 17:06:21 ]
サンクス!です

988 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 17:27:13 ]
これで出来ることはわかりましたが、char*からsize分だけ渡すにはどうすればいいですか。


std::ostream& operator<<(std::ostream& os, const ustring& x) {
return (os<<*****): }

989 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:15:23 ]
>>983
多くのプログラミング書籍が洋書からの翻訳であることを揶揄したジョークだろう
よく書かれるコピペみたいなものだ

990 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:22:42 ]
>>988
C/C++言語の仕様で\0まで出力だと思うので、任意の場所に\0を突っ込んでやればいいと思うよ。
バッファのオーバーランやアンダーランに気をつけて。

991 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:30:02 ]
\0があっても標準出力へ渡したいんです… ustringはchar*とintのペアです。
STLは使えません。
あと、別の質問があるのですが。

クラスのメンバ関数で、
char* & operator [] ( int n ) { return &(ch[n]); } だとエラーになります。
char* & operator [] ( int n ) { static char*p=&(ch[n]); return p; } だと通るのですが
同時にアクセス来た場合に困ります。
衝突しない参照渡しはどうやればいいですか。STL stringみてもよくわかりません。

992 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:39:11 ]
>>991
変数でもないものの参照を返したいとか訳分からん
値を返すんだと不都合なの?



993 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:39:28 ]
>991
やりたい事は本当に operator[] で char* & を返す事なのか?
ch って char* なんだよな?
string と名のつく型で operator[] だったら普通 char& が返ると思うんだが。

994 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:43:27 ]
値で返すと
memcpy(buf, &str[0], size);
が実行できないんです。

error メモリ上に配置されなければならない

がでます。
static char*の参照返しだと出ません。

995 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:44:35 ]
わかりました。間違えてました。>>993さんのご指摘通り間違えしてました。

996 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 19:05:39 ]
>>988 たのみます 
char* , intが与えられたときに標準出力( << )に\0を含む文字列を出力したいです。

997 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 19:31:43 ]
>>996
その前に、どういうインタフェースにしたいのか考えれ。
operator<< をオーバーロードすると
cout << yourclass << endl;
のような書き方ができるわけだが、
char*とintの二つのパラメータを与えるなら
そういう書き方はできなくなる。
それとも const char * operator()( int ) みたいなメンバを持たせて
cout << yourclass( 文字数 ) << endl;
とかけるようにでもするかい^^

998 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 19:37:28 ]
stringは、string(ch, size)で、\0を含む文字列を
cout<<に渡せるじゃないですか。
この実装はどうやってるのかわかりたいです。

999 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 19:45:50 ]
templateクラスのメソッドってnewしたら使われてなくても全部実体化しちゃう?

1000 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 20:03:01 ]
>>998
コンストラクタの話とoperator<<の話がごっちゃになってるじゃないか^^

1001 名前:1001 [Over 1000 Thread]
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<254KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef