- 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
- 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[]しているだろ?そのときだ。
- 379 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 18:04:57 ]
- >>375
newで割り当てたものはdelete、new[]で割り当てたものはdelete[]で解放します。参照の深さは関係ありません。
- 380 名前:デフォルトの名無しさん [2008/02/23(土) 18:12:04 ]
- 終端をセットしたいのですがどうやったらいいですか? コンパイルが通りません
main(){ char *ch=new char [50]; char **start, **end; start=&ch; //これは成功します end=&&ch[20]; // end=&(ch+20); }
- 381 名前:デフォルトの名無しさん [2008/02/23(土) 18:24:57 ]
- ch と &ch[0]は同じアドレスを表しますよね 20個目のアドレスは、&ch[20]ですよね
それを参照渡ししようとしたら&&ch[20]のはず・・・
- 382 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 18:26:38 ]
- char * chend = &ch[20];
end = &chend;
- 383 名前:デフォルトの名無しさん [2008/02/23(土) 18:33:33 ]
- >>382
コンパイルはできましたが、startと動作が違うようです main(){ char *ch=new char [50]; strcpy(ch,"abcdef"); char **start, **end; start=&ch; char * chend = &ch[20]; end = &chend; printf("%c\n", ((*start+1)[2]) ); printf("%c\n", ((*end-5)[2]) ); }
- 384 名前:デフォルトの名無しさん [2008/02/23(土) 18:34:48 ]
- 間違えました 20個を定義していませんでした
これだとうまくいきました サンクス char * chend = &ch[6]; end = &chend; printf("%c\n", ((*start+1)[2]) ); printf("%c\n", ((*end-5)[2]) );
- 385 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 18:38:15 ]
- なぜ「end = &&ch[20];」というか「end = &(&ch[20]);」ができないかは理解しておいてね。
- 386 名前:デフォルトの名無しさん [2008/02/23(土) 18:41:41 ]
- 再使用できるように動的確保したら複雑になってきました・・・
main(){ char *ch=new char [50]; strcpy(ch,"abcdef"); char **start, **end; start=&ch; char **chend =new char *; *chend=&ch[6]; end = &(*chend); printf("%c\n", ((*end-5)[2]) ); }
- 387 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 18:43:04 ]
- 先ずお前はnewを使うのをやめろ。話はそれからだ。
- 388 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 19:53:27 ]
- これはひどい
- 389 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 20:04:00 ]
- 何がしたのか全然わからない
- 390 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 20:04:21 ]
- 何度基礎をやり直せと言ったことか
- 391 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 20:26:55 ]
- なぜ、再使用しようとすると動的確保することになるのかもわからない。
文章で理由を説明してほしい。
- 392 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 20:36:55 ]
- なるほど、stringが出来るわけだ
- 393 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 20:53:56 ]
- おまえらほんと我慢強いよな。感心するよ
俺は>>386と同レベルのコードを保守する羽目になって殺意を覚えた。
- 394 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 21:00:35 ]
- 我慢強いというか、読んでない
- 395 名前:デフォルトの名無しさん [2008/02/23(土) 21:02:02 ]
- C++の授業で先生が、
int main() { int i; cin>>i; double a[i]; ... というコードはC++では出来ない(やりたいならnewでやるべき)と言われたのですが、 g++とiccではできました。これってだめだけど、gccやiccの拡張機能によって できているのでしょうか?
- 396 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 21:04:05 ]
- >>395
C++ が変化し続けているだけの話
- 397 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 21:09:33 ]
- >>395
現状のC++標準規格じゃ無理。C99は可能。 C99サポートしてるコンパイラなら期待してもいい。
- 398 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 21:11:02 ]
- newも使うべきではないよな。いやnew[]ではなくてstd::vector。
- 399 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 21:13:17 ]
- C99は正直あんまやらないでほしい
- 400 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 21:18:40 ]
- 可変引数マクロはマジホシス
- 401 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 21:24:18 ]
- 0xでおk
- 402 名前:デフォルトの名無しさん [2008/02/23(土) 21:35:03 ]
- おしえてください 下から2行目を動かすとデータが壊れるのですが原因がわかりません
#include <string.h> #include <stdio.h> #include <stdlib.h> typedef struct STRDATA{ char **st; char **end; }strdata; f(strdata x){ printf("%s",*(x.st)); } strconv(strdata *q, char **p){ char **chend =(char **)malloc(sizeof(char **)); q->st=p; *chend=&(*p)[strlen(*p)]; q->end = &(*chend);} strconstconv(strdata *q, char *p){ int n=strlen(p); char *ch=(char *) malloc(n+1); strcpy(ch,p); q->st=&ch; char **chen =(char **)malloc(sizeof(char **)); *chen=&(ch[n]); q->end = &(*chen);} main(){ strdata str; #define STR "abcdefgh" strconstconv(&str, STR); //ここをコメントアウトして一つ下を動かしても平気です //char *ch=new char [50]; strcpy(ch,STR); strconv(&str,&ch); //char *x=new char [1]; ここを動かすとおかしくなります f(str); }
- 403 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 21:37:15 ]
- もうお前いい加減諦めたら。
ローカル変数のアドレスを関数外に持ち出すな。
- 404 名前:デフォルトの名無しさん [2008/02/23(土) 21:39:05 ]
- char *x=new char [1]; が、なぜstrdata strを書き換えられるんでしょうか?
- 405 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 21:39:21 ]
- なんかまぁ・・・・・・いろいろとおつかれさん
- 406 名前:402 [2008/02/23(土) 21:45:20 ]
- おなじやつですが短くしました 下から2行目を動かすと壊れるのはなぜでしょうか
#include <string.h> #include <stdio.h> #include <stdlib.h> typedef struct STRDATA{ char **st; char **end; }strdata; f(strdata zzz){ printf("%s",*(zzz.st)); } strconstconv(strdata *q, char *p){ int n=strlen(p); char *ch=(char *) malloc(n+1); char **chen =(char **)malloc(sizeof(char **)); strcpy(ch,p); q->st=&ch; *chen=&(ch[n]); q->end = &(*chen);} main(){ strdata str; strconstconv(&str, "abcdefgh"); // char *test=new char [1]; f(str); }
- 407 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 21:46:36 ]
- まず変数のスコープを勉強しよう
- 408 名前:402 [2008/02/23(土) 21:48:09 ]
- なぜコメントアウトを外すとデータがこわれますか?
- 409 名前:デフォルトの名無しさん [2008/02/23(土) 21:53:31 ]
- newやmallocの確保は、解放しない限り残るんですよね そのアドレスは参照で受け取っているので問題ないと思うのですが
参照渡しにしてもだめです f(strdata *zzz){ printf("%s",*(zzz->st)); } main(){ strdata str; strconstconv(&str, "abcdefgh"); f(&str); }
- 410 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 21:54:33 ]
- 基礎からやりなおせよ
- 411 名前:デフォルトの名無しさん [2008/02/23(土) 21:56:58 ]
- ヒントください
- 412 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 21:57:01 ]
- いいから基礎からやりなおせって。スタックとヒープの概念すら分かってないだろ。
- 413 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 21:57:11 ]
- >>409
トリップをつけてくれるとあぼーんしやすいのですがいかがでしょうか
- 414 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 22:00:25 ]
- スタックとかヒープとか、この際関係ないレベルじゃん
- 415 名前:デフォルトの名無しさん [2008/02/23(土) 22:02:39 ]
- より短くしました これでも外すと壊れます なぜですか?
#include <string.h> #include <stdio.h> #include <stdlib.h> typedef struct { char **st; char **end; }strdata; f(strdata *q){ char *ch=(char *) malloc(10); strcpy(ch,"abcdef"); q->st=&ch; } g(strdata *zzz){ printf("%s",*(zzz->st)); } main(){ strdata str; f(&str); //char *test=new char [1]; g(&str); }
- 416 名前:デフォルトの名無しさん [2008/02/23(土) 22:03:36 ]
- >>409
多少手を入れて(int mainとするとか)こっちで動かしてみましたが、ちゃんとabcdefghと表示されました。 でも、newだけc++の機能をつかってるけど、あとは全部(結構年季が入った感じの)cだし、 c++のコンパイラなら、関数の戻り値を指定しないのはダメだと思うし、 mallocとnew は併用したらダメだってどこかで聞いたけどな。 いまいちやろうとしていることの意図がつかめません。 (mallocとnewを併用して、どういう状況でまずいのかしらべようとしているのか) もしc++を勉強しようとしているなら、なにか適当な本とかで勉強するのを勧めます。 Cを上記くらいご存知なら、すぐにC++も使えるようになりますよ。
- 417 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 22:03:53 ]
- ヒントもなにも>>403がずばり回答してるんだが。
これでもわからないなら、なんでもいいからポインタの無い言語に行ってくれ。 そして帰ってくんな。
- 418 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 22:08:06 ]
- >>415
なんでお前は答えを貰っても全くレスポンスを返さずに、 そんなヘドロみたいなコードを貼り続けるんだ。 頭沸いてるのか
- 419 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 22:08:35 ]
- >>415
これなら動く。 #include <string.h> #include <stdio.h> #include <stdlib.h> typedef struct { char *st; char *end; } strdata; void f(strdata *q) { char *ch=(char *)malloc(10); strcpy(ch,"abcdef"); q->st = ch; } void g(strdata *zzz) { printf("%s", zzz->st)); } int main() { strdata str; f(&str); g(&str); return 0; }
|

|