【初心者歓迎】C/C++室 Ver.49【環境依存OK】
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2008/02/20(水) 12:33:41ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。
【前スレ】
【初心者歓迎】C/C++室 Ver.48【環境依存OK】
http://pc11.2ch.net/test/read.cgi/tech/1202141921/
【アップローダー】(質問が長い時はココ使うと便利)
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm
0345デフォルトの名無しさん
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());
}
0346デフォルトの名無しさん
2008/02/23(土) 16:38:32f(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);}
0347デフォルトの名無しさん
2008/02/23(土) 16:38:490348デフォルトの名無しさん
2008/02/23(土) 16:41:160349デフォルトの名無しさん
2008/02/23(土) 16:42:49ポインタが参照渡しでどうのこうの言ってた奴だよな?
頼むからポインタとは何かを一から勉強し直してくれ。
0350デフォルトの名無しさん
2008/02/23(土) 16:44:23関数に渡された数値は数値がコピーされただけの別物。
だから関数内でx.start = new char [20];とかやっても呼び出し元のxには変化は無い。
0351デフォルトの名無しさん
2008/02/23(土) 16:44:320352デフォルトの名無しさん
2008/02/23(土) 16:45:30まともな本読め。
そこにいくらでもサンプルは書いてあるし、
詳細な解説も載ってる。
0353デフォルトの名無しさん
2008/02/23(土) 16:46:24後者はアドレス渡しですけど・・・
0354デフォルトの名無しさん
2008/02/23(土) 16:47:42後者では x は書き換えられるが ch は書き換えられない。
0355デフォルトの名無しさん
2008/02/23(土) 16:47:47アドレスの指す先の内容を書き換えると呼び出し元へ反映されるというだけのこと。
0356デフォルトの名無しさん
2008/02/23(土) 16:50:34ってやっても、ch と x->start がリンクされるわけじゃない
x->start の内容が変化しても、chには関係ない
0357デフォルトの名無しさん
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);}
0358デフォルトの名無しさん
2008/02/23(土) 16:52:50ch, x, そして動的に確保されたメモリが
実際にメモリ上でどう置かれていてどう参照していて
何を実行するとどう変化するか。
0359デフォルトの名無しさん
2008/02/23(土) 16:54:53それでとりあえずまともに動くね。
推奨されるコードかと言うとまたそれは別だが。
new 使ってるから C++ なんでしょ? コンテナ使えば楽だぜ。
0360デフォルトの名無しさん
2008/02/23(土) 16:58:05・>357のfに渡す前に、xはいつnewされてるの?
・関数の一行目がdeleteって、ものすごく気持ち悪いんだけど、よくつかう手法なの?
0361デフォルトの名無しさん
2008/02/23(土) 17:00:09deleteにNULLを渡しても何も起こらないことになっているから、
最初にnewされていないというのは大丈夫。エラーにはならない。
最初にdeleteというのは必要に応じて使えばいいと思うけど、
俺も書いた覚えない(clear()とかいかにもそれだけを行う関数というのでもない限り)。
0362デフォルトの名無しさん
2008/02/23(土) 17:03:440363デフォルトの名無しさん
2008/02/23(土) 17:04:300364デフォルトの名無しさん
2008/02/23(土) 17:04:41大問題。
0365デフォルトの名無しさん
2008/02/23(土) 17:05:560366デフォルトの名無しさん
2008/02/23(土) 17:06:160367デフォルトの名無しさん
2008/02/23(土) 17:07:46>deleteにNULLを渡しても何も起こらないことになっているから、
>最初にnewされていないというのは大丈夫。エラーにはならない。
なるほど、どうもです。
>最初にdeleteというのは必要に応じて使えばいいと思うけど、
>俺も書いた覚えない(clear()とかいかにもそれだけを行う関数というのでもない限り)。
なるほど。
よく考えたらC++になってからnewなんてほとんど使ったこと無かった気がします。
動的な配列が必要になったらだいたいvectorにつっこんでた。
0368デフォルトの名無しさん
2008/02/23(土) 17:10:42std::vector<int>().swap(v); みたいにしないとメモリは解放できない。
解放した方がいいかどうかは状況次第だが。
0369デフォルトの名無しさん
2008/02/23(土) 17:32:26大問題ってことで軽くググってみたら、
・配列に対して、delete [] としなかった場合、1個目の要素のみデストラクタが走り、残りの要素は走らない
・確保された領域(配列)は一応開放される(デストラクタで開放されるべき領域は除く)が、
要素数保持のための隠れた確保領域は開放されずに残る
ってな、感じかな
0370デフォルトの名無しさん
2008/02/23(土) 17:37:02#include <stdio.h>
main(){
char *ch=new char[200*1024*1024];
getchar();
printf("delete 実行\n");
delete ch;
getchar();}
0371デフォルトの名無しさん
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();}
0372デフォルトの名無しさん
2008/02/23(土) 17:42:39strch_idx関数に渡すためのcを、main関数のほうで作っておかないとだめかなと考えまして
>>332
あまり理解できませんが、なるべくforを使うようにします
>>333
消し忘れです
ご指摘ありがとうございます
>>334
理屈を丁寧に解説していただきありがとうございました
>>336を参考にやってみて、できました
>>336
ご丁寧にありがとうございました
その指針でできました
最後にご丁寧に、教えるのもわずらわしいような初歩的な愚問に答えていただき、ありがとうございました
0373デフォルトの名無しさん
2008/02/23(土) 17:44:350374デフォルトの名無しさん
2008/02/23(土) 17:47:40>>371
特に勘違いしてるところはないと思うが・・・
要素数を保持する領域はないってことを言いたいのか?
組み込み型にはないけど、クラスにはあるみたいなことが書いてあったんだが
0375デフォルトの名無しさん
2008/02/23(土) 17:49:37#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();}
0376デフォルトの名無しさん
2008/02/23(土) 17:50:41そもそもnew[]したものをdeleteするとどうなるかは未定義。
そういう挙動になったという話は、たまたまその実装ではそうだったということでしかない。
0377231
2008/02/23(土) 17:51:43MyArrayの方はデフォルトコンストラクタか引数を省略できるコンストラクタを
呼んでいるようなのですが、これのタイミングが分かりません。
コンストラクタを通過するそぶりもないし、一応初期化はされてるっぽいし・・・
特にデストラクタのタイミングも分からないのが心配です。
いつ開放されるんでしょうか?
0378デフォルトの名無しさん
2008/02/23(土) 17:54:33どこかでnew[]やdelete[]しているだろ?そのときだ。
0379デフォルトの名無しさん
2008/02/23(土) 18:04:57newで割り当てたものはdelete、new[]で割り当てたものはdelete[]で解放します。参照の深さは関係ありません。
0380デフォルトの名無しさん
2008/02/23(土) 18:12:04main(){
char *ch=new char [50];
char **start, **end;
start=&ch; //これは成功します
end=&&ch[20];
// end=&(ch+20);
}
0381デフォルトの名無しさん
2008/02/23(土) 18:24:57それを参照渡ししようとしたら&&ch[20]のはず・・・
0382デフォルトの名無しさん
2008/02/23(土) 18:26:38end = &chend;
0383デフォルトの名無しさん
2008/02/23(土) 18:33:33コンパイルはできましたが、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]) );
}
0384デフォルトの名無しさん
2008/02/23(土) 18:34:48これだとうまくいきました サンクス
char * chend = &ch[6];
end = &chend;
printf("%c\n", ((*start+1)[2]) );
printf("%c\n", ((*end-5)[2]) );
0385デフォルトの名無しさん
2008/02/23(土) 18:38:150386デフォルトの名無しさん
2008/02/23(土) 18:41:41main(){
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]) );
}
0387デフォルトの名無しさん
2008/02/23(土) 18:43:040388デフォルトの名無しさん
2008/02/23(土) 19:53:270389デフォルトの名無しさん
2008/02/23(土) 20:04:000390デフォルトの名無しさん
2008/02/23(土) 20:04:210391デフォルトの名無しさん
2008/02/23(土) 20:26:55文章で理由を説明してほしい。
0392デフォルトの名無しさん
2008/02/23(土) 20:36:550393デフォルトの名無しさん
2008/02/23(土) 20:53:56俺は>>386と同レベルのコードを保守する羽目になって殺意を覚えた。
0394デフォルトの名無しさん
2008/02/23(土) 21:00:350395デフォルトの名無しさん
2008/02/23(土) 21:02:02int main() {
int i;
cin>>i;
double a[i];
...
というコードはC++では出来ない(やりたいならnewでやるべき)と言われたのですが、
g++とiccではできました。これってだめだけど、gccやiccの拡張機能によって
できているのでしょうか?
0396デフォルトの名無しさん
2008/02/23(土) 21:04:05C++ が変化し続けているだけの話
0397デフォルトの名無しさん
2008/02/23(土) 21:09:33現状のC++標準規格じゃ無理。C99は可能。
C99サポートしてるコンパイラなら期待してもいい。
0398デフォルトの名無しさん
2008/02/23(土) 21:11:020399デフォルトの名無しさん
2008/02/23(土) 21:13:170400デフォルトの名無しさん
2008/02/23(土) 21:18:400401デフォルトの名無しさん
2008/02/23(土) 21:24:180402デフォルトの名無しさん
2008/02/23(土) 21:35:03#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); }
0403デフォルトの名無しさん
2008/02/23(土) 21:37:15ローカル変数のアドレスを関数外に持ち出すな。
0404デフォルトの名無しさん
2008/02/23(土) 21:39:050405デフォルトの名無しさん
2008/02/23(土) 21:39:210406402
2008/02/23(土) 21:45:20#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); }
0407デフォルトの名無しさん
2008/02/23(土) 21:46:360408402
2008/02/23(土) 21:48:090409デフォルトの名無しさん
2008/02/23(土) 21:53:31参照渡しにしてもだめです
f(strdata *zzz){ printf("%s",*(zzz->st)); }
main(){
strdata str;
strconstconv(&str, "abcdefgh");
f(&str); }
0410デフォルトの名無しさん
2008/02/23(土) 21:54:330411デフォルトの名無しさん
2008/02/23(土) 21:56:580412デフォルトの名無しさん
2008/02/23(土) 21:57:010413デフォルトの名無しさん
2008/02/23(土) 21:57:11トリップをつけてくれるとあぼーんしやすいのですがいかがでしょうか
0414デフォルトの名無しさん
2008/02/23(土) 22:00:250415デフォルトの名無しさん
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); }
0416デフォルトの名無しさん
2008/02/23(土) 22:03:36多少手を入れて(int mainとするとか)こっちで動かしてみましたが、ちゃんとabcdefghと表示されました。
でも、newだけc++の機能をつかってるけど、あとは全部(結構年季が入った感じの)cだし、
c++のコンパイラなら、関数の戻り値を指定しないのはダメだと思うし、
mallocとnew は併用したらダメだってどこかで聞いたけどな。
いまいちやろうとしていることの意図がつかめません。
(mallocとnewを併用して、どういう状況でまずいのかしらべようとしているのか)
もしc++を勉強しようとしているなら、なにか適当な本とかで勉強するのを勧めます。
Cを上記くらいご存知なら、すぐにC++も使えるようになりますよ。
0417デフォルトの名無しさん
2008/02/23(土) 22:03:53これでもわからないなら、なんでもいいからポインタの無い言語に行ってくれ。
そして帰ってくんな。
0418デフォルトの名無しさん
2008/02/23(土) 22:08:06なんでお前は答えを貰っても全くレスポンスを返さずに、
そんなヘドロみたいなコードを貼り続けるんだ。
頭沸いてるのか
0419デフォルトの名無しさん
2008/02/23(土) 22:08:35これなら動く。
#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;
}
0420デフォルトの名無しさん
2008/02/23(土) 22:11:12おまいやさしいな
0421デフォルトの名無しさん
2008/02/23(土) 22:14:15それだと、ポインタは値渡しのため、strに渡した文字列が書き換えられなくなります
削ったのですがこれでも原因が不明です コンパイラはBCC5.5です
#include <stdio.h>
#include <stdlib.h>
typedef struct { char **st; }strdata;
f(strdata *q){
char *ch=(char *) malloc(10);
ch[0]='X';ch[1]='Y';ch[2]='Z';ch[3]=0;
q->st=&ch; }
main(){
strdata str; f(&str);
//char *test=(char *) malloc(1);
printf("%s",*(str.st));}
0422デフォルトの名無しさん
2008/02/23(土) 22:17:54( ゚д゚) ・・・
(つд⊂)ゴシゴシ
(;゚д゚) ・・・
(つд⊂)ゴシゴシゴシ
_, ._
(;゚ Д゚) …!?
0423デフォルトの名無しさん
2008/02/23(土) 22:17:550424デフォルトの名無しさん
2008/02/23(土) 22:20:55#include <stdio.h>
#include <stdlib.h>
typedef struct { char **st; }strdata;
void f(strdata *q){
char *ch=(char *) malloc(10);
ch[0]='X';ch[1]='Y';ch[2]='Z';ch[3]=0;
q->st=&ch; }
int main(){
strdata str;
char *test;
f(&str);
test=(char *)malloc(1);
printf("%s",*(str.st));
getchar(); return 0;}
0425デフォルトの名無しさん
2008/02/23(土) 22:21:34>それだと、ポインタは値渡しのため、strに渡した文字列が書き換えられなくなります
wwwwwwwwwwwwwwwwwwwwwww
>>419よ、これが現実だwwwwwアホは相手にするなwwwwww
0426デフォルトの名無しさん
2008/02/23(土) 22:22:150427421
2008/02/23(土) 22:26:270428デフォルトの名無しさん
2008/02/23(土) 22:28:05初心者を抜け出した程度の俺でも酷いと思うw
0429デフォルトの名無しさん
2008/02/23(土) 22:28:08変数testの用途が不明だったので、削除させてもらった。
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *st;
}strdata;
void f(strdata *q) {
char *ch = (char *)malloc(10);
ch[0] = 'X';
ch[1] = 'Y';
ch[2] = 'Z';
ch[3] = '\0'; //まあ0のままでもいいんだけど
q->st = ch;
}
int main() {
strdata str;
f(&str);
printf("%s", str.st);
getchar();
free(str.st);
return 0;
}
0430421
2008/02/23(土) 22:28:56#include <string.h>
#include <stdio.h>
typedef struct { char *st; }strdata;
f(strdata *x){
delete x->st;
x->st = new char [9];
strcpy(x->st,"++++++"); }
main(){
char *ch=NULL;
strdata x;
x.st=ch;
f(&x);
printf("%s",ch);}
0431デフォルトの名無しさん
2008/02/23(土) 22:34:49お前が421や424で書いたコードは
>printf("%s",*(str.st));
だったのになぜ
>printf("%s",ch);
になってるんだ?納得のいく説明を聞こうか?
0432デフォルトの名無しさん
2008/02/23(土) 22:34:55int main() {
strdata str;
f(&str); ←ここで初期化された文字列の内容、長さを変更したいんです あと変数testほ確保しても落ちないようにしたいんです
printf("%s", str.st);
みなさんは、>>424はまともに動きますか?
0433デフォルトの名無しさん
2008/02/23(土) 22:37:26動かすまでもなく、まともに動かないのは分かる
0435デフォルトの名無しさん
2008/02/23(土) 22:37:36printf("%s",ch);をprintf("%s",x.st);とすればいい。
嫌か?
じゃあこれでどうだ。
#include <string.h>
#include <stdio.h>
typedef struct {
char *st;
} strdata;
void f(strdata *x) {
delete x->st;
x->st = new char[9];
strcpy(x->st,"++++++");
}
int main() {
char *ch = NULL;
strdata x;
x.st = ch;
f(&x);
ch = x.st;
printf("%s",ch);
delete[] ch;
return 0;
}
0436デフォルトの名無しさん
2008/02/23(土) 22:39:36test=(char *)malloc(1);をはずすと上手くいきます なぜですか
0437デフォルトの名無しさん
2008/02/23(土) 22:40:58それは上手く動いてるんじゃなくて、たまたま動いてるだけ
0438デフォルトの名無しさん
2008/02/23(土) 22:41:46をチラ見しかしてないけどそれが動くことがとても不思議。
とりあえず期待する動作はなんなのかを日本語で書いてください。
0439デフォルトの名無しさん
2008/02/23(土) 22:42:06それだと始めにchが巨大に確保されていたらメモリーリークになると思うのですが
0440デフォルトの名無しさん
2008/02/23(土) 22:43:20偶然。
あのコードでは、すでになくなったローカル変数を読み取ろうとしている。
運良くメモリ上に残っていれば、一見正しく動いているように見える。
そのtestの行は、残っていた変数の値を破壊する決定打になったのだろう。
0441デフォルトの名無しさん
2008/02/23(土) 22:43:21思うだけだ
0442デフォルトの名無しさん
2008/02/23(土) 22:44:24高速スクロールで華麗にスルー。
違うお題ないの?
0443デフォルトの名無しさん
2008/02/23(土) 22:46:11use LWP::Simple;
sub foo{ return get('ttp://hoge.com/fuga.zip'); }
これをVC++で極力シンプルにやるにはどうすればいいでしょうか?
環境は以下のとおりです。
VisualC++.net2003 Standard
managedC++不使用 MFC不使用 ATL/WTL使用 STL/Boost使用
0444デフォルトの名無しさん
2008/02/23(土) 22:46:57バイナリ文字列 (\0を含む) の初めと終わりを構造体で関数に渡して、バイナリ文字列の内容、長さを書き換えたいんです
0445444
2008/02/23(土) 22:48:45■ このスレッドは過去ログ倉庫に格納されています