- 1 名前:デフォルトの名無しさん [2008/02/20(水) 12:33:41 ]
- エスケープシーケンスやWin32APIなどの環境依存なものでもOK。
ただしその場合、質問者は必ず環境を書きましょう。 ※sage禁止です(と代々スレに書いてありますが自己判断で)。 【前スレ】 【初心者歓迎】C/C++室 Ver.48【環境依存OK】 pc11.2ch.net/test/read.cgi/tech/1202141921/ 【アップローダー】(質問が長い時はココ使うと便利) kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm
- 278 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:15:15 ]
- C言語は基本的にすべてコピーで渡す
ポインタもコピー
- 279 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:15:51 ]
- >>275
C には参照渡しなんてないんだよ。
- 280 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:18:09 ]
- 参照渡しがアドレス渡しの糖衣ってのは正しい
どっちかだけ知らずに語ると馬鹿なことになるけど、どっちもしっかり理解してるなら別に問題ないでしょう
- 281 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:20:52 ]
- static_castと(int)みたいなキャストってなにかなにか違うんですか?
- 282 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:24:24 ]
- >>281
static_castの方が用途が限定される
- 283 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:24:35 ]
- >>280
個人がそう理解するのはかまわんけど、初心者への説明としては不親切じゃね?
- 284 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:25:07 ]
- >>281
Cとの互換性を大事にしたいなら後者、意味をはっきりさせたいのなら前者を使うといいでしょう。
- 285 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:26:18 ]
- >>273
実際やってみると cuで2が、gguで3が、ijcoで4が返ってきます これは、s[i] == cと、s[i] == 0の判定が成されていないという事ですよね? しかし、while関数自体は終わってるので、s[i]は判定されている どういうことなんでしょうか? また、ご指摘を受けて、whileをdo-whileに変更しました、ありがとうございます
- 286 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:27:11 ]
- なんでそんな単純な構造でgotoを使う必要があるのか解らん。
- 287 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:30:00 ]
- gotoは怖くて使えない・・・
てか絶対使わないようにしてるんだが、違うのか
- 288 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:31:58 ]
- >>280
単なる構文糖衣じゃない。 参照の参照というのは存在しないが、 ポインタのポインタというのは存在する。 これは大きな違いで、適当な教え方してると >>207 みたいなやつが出てくる。
- 289 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:33:55 ]
- >>287
むしろ使った方が綺麗になる状況では使う。 でも、上のは break; 使えば解決できることで、 goto を使って解決すべきじゃない。
- 290 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:37:52 ]
- >>282
>>284 当面はあまり気にしなくてよさそうですね どうもありがとうございました
- 291 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:39:03 ]
- >>290
いいや、気にしろ。
- 292 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:42:06 ]
- 普通は C 風のキャストは使うべきじゃない。
せいぜいクラスのテンポラリオブジェクトを作るのに関数風のキャストを使うくらい。
- 293 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:47:55 ]
- >>292
それはキャストよりもコンストラクタ呼び出しのほうがしっくりくる
- 294 名前:デフォルトの名無しさん [2008/02/23(土) 14:49:30 ]
- 昨日質問したものですが、char * 型とchar []を判別する方法はありませんか?
- 295 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:52:19 ]
- ソースコードを読みましょう。
- 296 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:54:36 ]
- >>291
すいません 気にしろとだけ言われましてもなにに気を使えばいいのかわかりません まずい点でもでてくるのか だとかを教えていただけませんか
- 297 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 14:58:13 ]
- キャストには色々意味があって、C言語風キャストだとそれらをすべて内包してしまって意図が掴みにくい
- 298 名前:デフォルトの名無しさん [2008/02/23(土) 14:58:20 ]
- メインウインドウにBUTTONを作成するときなどで使う、
CreateWindowとCreateControlWindowはどう違いますか?
- 299 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:00:58 ]
- >>296
C風のキャストはなんでもかんでもキャストできてしまうので、 プログラマの意図と違ってても警告が出ない const void *p = 〜; char *q = (char*)p; // charにキャスト・・・あれ? constも外しちゃったよ! でも警告は出ない char *r = static_cast<char*>(p); // コンパイルエラー: static_castでconstは外せない char *s = const_cast<char*>(static_cast<const char*>(p)); // constも外したい意図の場合はこう書く
- 300 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:03:54 ]
- >>286-287
gotoのほうが行き先が明確になるので、理解しやすかったので、用いていますが なぜ怖いのでしょうか それと、「これは、s[i] == cと、s[i] == 0の判定が成されていないという事ですよね? しかし、while関数自体は終わってるので、s[i]は判定されている どういうことなんでしょうか? 」 これにも答えていただけると非常にありがたいです
- 301 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:04:05 ]
- >>296
キャストというのは基本的にマズい処理。 アップキャストだけは例外的に安全だが、 それ以外は基本的にはあまりやるべきではない。 でも、実際にはどうしてもやる必要が出てくる事もある。 こればっかりは仕方が無い。 そういう時、C 風のキャストを使ってしまうと色々と問題が発生する。 ・ 間違って危険なキャストをしてしまうかもしれない。 例えば、const を付けるべきところで const を付け忘れたり。 こういう時、static_cast なら危険な const の付け忘れがあるとコンパイルエラーになる。 C 風キャストだと問答無用でキャストされてしまう。 これが一番の問題。 ・ キャストが原因っぽいバグが見つかった時、どこにキャストがあるのか探すのが面倒。 C++ のキャストだと検索でキャストを行っている箇所を簡単に見つけられる。 ・ キャストがあまり目立たない。 危険な処理を行っている箇所が目立たないのは危険。 C++ のキャストは非常に目立つ。 ・ 打鍵数が少ないので気軽にキャストをしてしまう。 C++ のキャストは打ち込むのが面倒で、キャストを本当に使うべきなのか 立ち止まって考えるよう思考を誘導してくれるかもしれない。 ・ 今行おうとしているキャストはどういうものかをあまり意識しないかもしれない。 キャストという処理を軽く見ているのはよろしくない。
- 302 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:06:01 ]
- >>300
gotoが必要になるのは言語の構造化能力を超えた構造が必要になる場合であって、 この場合はそういう場合でない。
- 303 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:06:12 ]
- >>300
論理的に記述しようぜ。 「while を終了する」 と 「指定位置に移動する」 では 前者の方がより論理的だ。 論理的なコードは、一般に変更に強く、バグが出にくい。 まあ、break すらみだりに使うべきじゃないという人もいるけどね。
- 304 名前:デフォルトの名無しさん [2008/02/23(土) 15:07:50 ]
- 関数の引数で、char * 型とchar []型を判別する方法ありますか?
- 305 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:09:39 ]
- >>304
不可能
- 306 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:10:05 ]
- void foo(char* const& hoge);
template <size_t N> void foo(char (&hoge)[N]); と区別できなくはない。
- 307 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:12:02 ]
- char[N]とchar[]は別物だと思うよ。
- 308 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:12:33 ]
- void foo(char* hoge, size_t size);
template <size_t N> inline void foo(char (&hoge)[N]) { foo(hoge, N); } もちろん、こう実装するんだぜ。
- 309 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:13:12 ]
- そう言う意味での char [] 型なんてそもそも存在しないが。
- 310 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:13:14 ]
- >>285
>cuで2が、gguで3が、ijcoで4が返ってきます その書き方はおかしい strch_idxには引数が2つあるので、cuとかgguだけでは結果は決まらないはずだ
- 311 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:13:24 ]
- >>300
逆。 gotoの方がどこにでも飛ばせるせいで行き先が不明確になる。 自分の書いたコードを他人に読ませることを想像してごらん。 breakならどこに飛ぶのか一目瞭然だけど、gotoだといちいちラベルを検索しないといけない。 しかもbreakなら「ループの終了」という意図が一目瞭然だけど、 gotoだとどういう意図で飛ばしたのかを考えないといけない。 そういう理由でgotoは避けられるため、安易にgotoが入っているとさらに、 「gotoを使わなければいけないどんな理由があったのか?」と考えさせることになる。
- 312 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:14:13 ]
- int⇔floatの変換だけでも、毎回static_cast使う?
あと、コンテナの最後の要素以外を処理する時、 std::vector<T> container; for (int n = 0; n < static_cast<int>(container.size()) - 1; ++n) container[n] = ...; ってやる?
- 313 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:23:01 ]
- >>312
俺はstatic_castを使う コンテナの方は for (size_t n = 0; 〜 って書けばいいのでは 本当は std::vector<T>::size_type の方が適切なのかもしれんが
- 314 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:23:54 ]
- >>312
>int⇔floatの変換 うん。 >最後の要素以外を処理 unsigned使う。
- 315 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:31:10 ]
- >int⇔floatの変換だけでも、毎回static_cast使う?
使う。 >コンテナの最後の・・・ for (std::vector<T>::size_type n = 0, size = container.size(); n + 1 < size; ++n) container[n] = ...; ってやると思う。 符号無しの値を符号付きにキャストするのは基本的に危険だと思う。
- 316 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:32:52 ]
- 後者の場合、
if( !c.empty() ) for( size_t n=0; n<c.size()-1; ++n) で何か問題あるのか?
- 317 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:34:18 ]
- >>316
n + 1 < c.size() で判定すれば empty チェックは要らない。
- 318 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:36:12 ]
- typename 忘れてた。
まあ T をそういう意味で使ってるとは限らないが。
- 319 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:39:01 ]
- >>302 >>303
>>311での説明とほぼ同じという理解でよろしいでしょうか >>311 gotoよりbreakを使うべきというのは、よく理解でき、納得できました しかし、怖いというのは一体 >>310 すみませんが、もうすこし噛み砕いて説明願えないでしょうか const char* sには、任意の文字列が入って、char cで、検索する文字を固定という事ではないんですか? そのconst char* sにcuですとか、gguですとかが入っているので、これで十分だと考えているのですが
- 320 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:43:08 ]
- >>319
goto はまず特定の状況でしか使われない。 それ以外で使われると混乱するし、 何のために使われているかすぐに分からないので不気味で怖い。
- 321 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:44:11 ]
- >>319
goto は意図が不明確。 goto のあるコードを変更することになった場合、 その意図が 100% 分からなければ、 手を加えて変なことになりかねないので怖い。
- 322 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:44:56 ]
- >>319
一番怖いのは、バグの温床になること。 コードの分かりにくさってのはバグに直結する。
- 323 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:47:14 ]
- >>315
イテレータ使うならこうだな。 前進イテレータでさえあれば、これでいけるはず。 if(! container.empty()) { Iter it_next = container.begin(); ++it_next; for(Iter it = container.begin(), end = container.end(); it_next != end; ++it, ++it_next) *it = ...; }
- 324 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:52:18 ]
- >>319
const char* s が cu でも c の方は strch_idx("cu", 'c') とか strch_idx("cu", 'u') とか strch_idx("cu", 'x') とか色々指定できるわけで
- 325 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:53:30 ]
- >>320-322
なるほど、よく理解できました ご親切にありがとうございます 1、意図が不明で不気味で怖い 2、バグを招きやすいから怖い この二点ですね そして、本筋のほうもできたら説明していただきたいのですが
- 326 名前:デフォルトの名無しさん [2008/02/23(土) 15:53:54 ]
- STLつかうとコンパイルに時間かかりますけど、クラスも多少鈍くなるんですか?
- 327 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:58:00 ]
- そもそも while じゃなくて for 使おうぜ。
- 328 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 15:58:55 ]
- >>326
一般に、コンパイルに時間がかかる方が、 コンパイル時にある程度処理を行ってくれているため、速くなる。 ただ、コードがあまりにも肥大してくると、 キャッシュの効きが悪くなって遅くなる事もある。
- 329 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:02:03 ]
- >>325
いくつか修正したみたいだけど今はどうなってるの?
- 330 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:05:44 ]
- >>324 >>329
最初から全文現すべきでしたね、申し訳ありません #include <iostream> using namespace std; int strch_idx(const char* s, char c) { int i = 0; do { if(s[i] == c) goto end; else if(s[i] == 0) { i = -1; break; } i++; } while(s[i]); return i; } int main() { cout << "文字列を入力:"; char p[] = ""; cin >> p; char c = c; cout << strch_idx(p, c); return 0; } >>327 forだと、終了させるための条件が思いつかなかったので、whileにしましたが、やはりforのほうが良い理由があるのでしょうか
- 331 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:07:30 ]
- >>330
>char c = c; これはなによ
- 332 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:08:43 ]
- >>330
continue した時でもインデックスが増えてくれるのと、 インデックスをなめていく操作を行っているという意図が伝わりやすいのと。 終了条件は while の時と同じでいいじゃん?
- 333 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:16:31 ]
- >>330
goto end ってどこに飛んでるの?
- 334 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:17:17 ]
- >>330
goto endが一個消し忘れ。 ×char c = c; ○char c = 'c'; -1を返したいのは文がヌル文字だけだった場合?それとも文字が見つからなかった場合? 前者ならループのたび判定するのは無駄だから最初に一回だけ判定させたらいい。 後者ならヌルが見つかった時点でループが終わってるから中のlese-if節は判定してくれない。 最初に文字列の長さを測って最後までループが回った場合に-1を返すようにしないと。
- 335 名前:デフォルトの名無しさん [2008/02/23(土) 16:26:11 ]
- f(x)のあとでstrlen(ch)が1になることがあります もとのソースを簡略にしました
構造体を参照渡ししてもだめでした 下は期待通りの動作をします 何がいけないのかわかりません #include <string.h> #include <stdio.h> typedef struct STRDATA{ char *start; char *end;}strdata; f(strdata x){ delete x.start; x.start = new char [20]; strcpy(x.start,"++++++++++++++"); } main(){ char *ch=new char [10]; strcpy(ch,"uuuu"); strdata x; x.start=ch; x.end=ch+strlen(ch); f(x); printf("%s",ch);}
- 336 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:26:35 ]
- なんで do-while になってるんだろう。
もっと単純に考えようぜ。 まず、文字を1つずつ取得していくループを書く。 for(i = 0; /* 文字列が終了するまで */; i++) { /* s[i] で文字を先頭から順番に走査していける */ } んで次に、c が見つかったらインデックスを返すようにする。 for(i = 0; /* 文字列が終了するまで */; i++) { /* s[i] が c なら i を返す */ } そして、検索しても c が見つからなかった場合は -1 を返す。 for(i = 0; /* 文字列が終了するまで */; i++) { /* s[i] が c なら i を返す */ } /* -1 を返す */ これでおk。
- 337 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:29:05 ]
- >>304
Cならシーキビだろ C++か? template<typename T> struct IsArray { enum { value = 0 }; }; template<typename T, size_t N> struct IsArray<T[N]> { enum { value = 1 }; }; template<typename T> bool test(const T&) { return IsArray<T>::value; } template<typename T> void f(const T& t) { if(test(t)) cout << "配列だ" << endl; else cout << "配列じゃない" << endl; }
- 338 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:29:46 ]
- てか、C++ならブースト使えよか
- 339 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:30:19 ]
- >>335
f の呼び出し後、ch は既に delete された後のアドレスを保持することになるから 絶対にアクセスしちゃダメ。 そもそも生のポインタで確保されたメモリを扱ってるからそういう事が起きる。 コンテナ使え。
- 340 名前:デフォルトの名無しさん [2008/02/23(土) 16:30:21 ]
- これだとエラーで止まります どうすればいいですか
f(strdata *x){ delete x->start; x->start = new char [20]; strcpy(x->start,"++++++++++++++"); } main(){ char *ch=NULL; strdata x; x.start=ch; x.end=ch+strlen(ch); f(&x); printf("%s",ch);}
- 341 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:31:18 ]
- >>335
chに割り当てたnew char[10]はfの中でdeleteされてるから、 printf("%s",ch) は違法。 それからnew[]した配列はdeleteではなくdelete[]しないといけない。
- 342 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:34:08 ]
- >>340
char *ch=NULL; x.end=ch+strlen(ch); ヌルポインタに整数を足しても有効な値にはならない。
- 343 名前:デフォルトの名無しさん [2008/02/23(土) 16:35:22 ]
- バイナリ文字列の始めと終わりを構造体で渡して、内容、サイズを書き換えるには
>>335をどう変更すればできますか?
- 344 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:37:35 ]
- 普通に先頭のポインタとstrlen使って適当に操作したらいいんちゃう?
- 345 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:38:25 ]
- バイナリ・・・文字列??
それはともかく、std::string 使え。 #include <string> void f(string& str) { str = "++++++++++++++"; } int main() { std::string str("++++"); printf("%s\n", str.c_str()); f(str); printf("%s\n", str.c_str()); }
- 346 名前:デフォルトの名無しさん [2008/02/23(土) 16:38:32 ]
- このふたつは動きますが内容が変化しません なぜですか
f(strdata x){ delete x.start; x.start = new char [20]; strcpy(x.start,"++++"); } main(){ char *ch=NULL; strdata x; x.start=ch; f(x); printf("%s",ch);} f(strdata *x){ delete x->start; x->start = new char [20]; strcpy(x->start,"++++"); } main(){ char *ch=NULL; strdata x; x.start=ch; f(&x); printf("%s",ch);}
- 347 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:38:49 ]
- 1つ目、std:: 忘れた。
- 348 名前:デフォルトの名無しさん [2008/02/23(土) 16:41:16 ]
- C言語だけで、0を含む文字列を変化させたいのですが、できないですか?
- 349 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:42:49 ]
- >>346
ポインタが参照渡しでどうのこうの言ってた奴だよな? 頼むからポインタとは何かを一から勉強し直してくれ。
- 350 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:44:23 ]
- >>346
関数に渡された数値は数値がコピーされただけの別物。 だから関数内でx.start = new char [20];とかやっても呼び出し元のxには変化は無い。
- 351 名前:デフォルトの名無しさん [2008/02/23(土) 16:44:32 ]
- f(x)で、(バイナリ)文字列を書き換えられるやり方教えてください それみて勉強します
- 352 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:45:30 ]
- >>351
まともな本読め。 そこにいくらでもサンプルは書いてあるし、 詳細な解説も載ってる。
- 353 名前:デフォルトの名無しさん [2008/02/23(土) 16:46:24 ]
- >>350
後者はアドレス渡しですけど・・・
- 354 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:47:42 ]
- >>353
後者では x は書き換えられるが ch は書き換えられない。
- 355 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:47:47 ]
- >>353
アドレスの指す先の内容を書き換えると呼び出し元へ反映されるというだけのこと。
- 356 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:50:34 ]
- x->start = ch
ってやっても、ch と x->start がリンクされるわけじゃない x->start の内容が変化しても、chには関係ない
- 357 名前:デフォルトの名無しさん [2008/02/23(土) 16:52:12 ]
- これで正解でしょうか?
#include <string.h> #include <stdio.h> typedef struct STRDATA{ char **start; char **end;}strdata; f(strdata x){ delete *(x.start); *(x.start) = new char [20]; strcpy(*(x.start),"++++++++++++++"); } main(){ char *ch=NULL; strdata x; x.start=&ch; f(x); printf("%s",ch);}
- 358 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:52:50 ]
- 図を描こうぜ。図を。
ch, x, そして動的に確保されたメモリが 実際にメモリ上でどう置かれていてどう参照していて 何を実行するとどう変化するか。
- 359 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:54:53 ]
- >>357
それでとりあえずまともに動くね。 推奨されるコードかと言うとまたそれは別だが。 new 使ってるから C++ なんでしょ? コンテナ使えば楽だぜ。
- 360 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 16:58:05 ]
- 横から質問で申し訳ないんだけど、
・>357のfに渡す前に、xはいつnewされてるの? ・関数の一行目がdeleteって、ものすごく気持ち悪いんだけど、よくつかう手法なの?
- 361 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 17:00:09 ]
- >>360
deleteにNULLを渡しても何も起こらないことになっているから、 最初にnewされていないというのは大丈夫。エラーにはならない。 最初にdeleteというのは必要に応じて使えばいいと思うけど、 俺も書いた覚えない(clear()とかいかにもそれだけを行う関数というのでもない限り)。
- 362 名前:デフォルトの名無しさん [2008/02/23(土) 17:03:44 ]
- サンクス たびたびどうもありがとうございます
- 363 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 17:04:30 ]
- 俺も横レスだけど、配列なのに delete [] にしてないのは問題ないのか?
- 364 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 17:04:41 ]
- >>363
大問題。
- 365 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 17:05:56 ]
- だからコンテナを使おうぜと言ってるのに。
- 366 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 17:06:16 ]
- いろいろな意味で気持ち悪い。というか何をしたいのかよくわからない。
- 367 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 17:07:46 ]
- >361
>deleteにNULLを渡しても何も起こらないことになっているから、 >最初にnewされていないというのは大丈夫。エラーにはならない。 なるほど、どうもです。 >最初にdeleteというのは必要に応じて使えばいいと思うけど、 >俺も書いた覚えない(clear()とかいかにもそれだけを行う関数というのでもない限り)。 なるほど。 よく考えたらC++になってからnewなんてほとんど使ったこと無かった気がします。 動的な配列が必要になったらだいたいvectorにつっこんでた。
- 368 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 17:10:42 ]
- clear はメモリが解放される訳じゃないんだよな。
std::vector<int>().swap(v); みたいにしないとメモリは解放できない。 解放した方がいいかどうかは状況次第だが。
- 369 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 17:32:26 ]
- >>364
大問題ってことで軽くググってみたら、 ・配列に対して、delete [] としなかった場合、1個目の要素のみデストラクタが走り、残りの要素は走らない ・確保された領域(配列)は一応開放される(デストラクタで開放されるべき領域は除く)が、 要素数保持のための隠れた確保領域は開放されずに残る ってな、感じかな
- 370 名前:デフォルトの名無しさん [2008/02/23(土) 17:37:02 ]
- 勘違いしてないか?タスクマネージャで確認してみ
#include <stdio.h> main(){ char *ch=new char[200*1024*1024]; getchar(); printf("delete 実行\n"); delete ch; getchar();}
- 371 名前:デフォルトの名無しさん [2008/02/23(土) 17:40:15 ]
- これでも解放するし
#include <stdio.h> main(){ int n; char **ch=new char*[200]; for(n=0;n<200;n++)ch[n]=new char [1024*1024]; getchar(); printf("delete 実行\n"); for(n=0;n<200;n++)delete ch[n]; getchar();}
- 372 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 17:42:39 ]
- >>331
strch_idx関数に渡すためのcを、main関数のほうで作っておかないとだめかなと考えまして >>332 あまり理解できませんが、なるべくforを使うようにします >>333 消し忘れです ご指摘ありがとうございます >>334 理屈を丁寧に解説していただきありがとうございました >>336を参考にやってみて、できました >>336 ご丁寧にありがとうございました その指針でできました 最後にご丁寧に、教えるのもわずらわしいような初歩的な愚問に答えていただき、ありがとうございました
- 373 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 17:44:35 ]
- これが初心者歓迎スレの良心。
- 374 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 17:47:40 ]
- >>370
>>371 特に勘違いしてるところはないと思うが・・・ 要素数を保持する領域はないってことを言いたいのか? 組み込み型にはないけど、クラスにはあるみたいなことが書いてあったんだが
- 375 名前:デフォルトの名無しさん [2008/02/23(土) 17:49:37 ]
- これだと解放しないけど・・・ *xと定義されているなら、deleteを使うのでは? []は**xを解放する場合でしょ
#include <stdio.h> main(){ char **ch=new char*[200]; for(int n=0;n<200;n++)ch[n]=new char [1024*1024]; getchar(); printf("delete 実行\n"); delete[] ch; // delete ch; getchar();}
- 376 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 17:50:41 ]
- >>369
そもそもnew[]したものをdeleteするとどうなるかは未定義。 そういう挙動になったという話は、たまたまその実装ではそうだったということでしかない。
- 377 名前:231 mailto:sage [2008/02/23(土) 17:51:43 ]
- 今更ですが>>231のようなことをした時に
MyArrayの方はデフォルトコンストラクタか引数を省略できるコンストラクタを 呼んでいるようなのですが、これのタイミングが分かりません。 コンストラクタを通過するそぶりもないし、一応初期化はされてるっぽいし・・・ 特にデストラクタのタイミングも分からないのが心配です。 いつ開放されるんでしょうか?
- 378 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 17:54:33 ]
- >>377
どこかでnew[]やdelete[]しているだろ?そのときだ。
|

|