トップページ⇒tech
104コメント31KB

文字列配列の動的生成についての質問.

■ このスレッドは過去ログ倉庫に格納されています
0001あきらNGNG
C++で,文字列の配列を動的に生成するとき


char** a = new char*[3];

for (int i = 0; i < 3; i++) {
char s[256];
cout << "a[" << i << "] = ";
cin >> s;

a[i] = new char[strlen(s) + 1];  //「ここ」
strcpy(a[i], s);         //「ここ」
}

for (int i = 0; i < 3; i++) {
cout << "a[" << i << "] = " << a[i] << '\n';
}
delete[] a;

上のプログラムで「ここ」の部分を
a[i] = s;
と置き換えるのがどうしてダメなのか,どうしても理解できません.
どなたか教えてもらえませんか??

0002デフォルトの名無しさんNGNG
初!
2ゲットズサー
00033NGNG
初!
3ゲットズサー
0004デフォルトの名無しさんNGNG
char** なんて使わないで vector<string> を使いましょう。

〜〜〜〜〜〜〜〜〜 糸冬 〜〜〜〜〜〜〜〜〜
0005デフォルトの名無しさんNGNG
> delete[] a;
これではメモリリークしています。
〜〜〜〜〜〜〜〜〜 糸冬 〜〜〜〜〜〜〜〜〜
0006デフォルトの名無しさんNGNG
>>1
いいんじゃないの?
エラー出たの?
0007あきらNGNG
>>4さん
ありがとうございます.便利なのがあるみたいですね!
ただ,いま勉強中で理解できない問題が出てきたので(>_<;)
0008あきらNGNG
>>5さん
では,どうやって解放すべきでしょうか??
>>6さん
書き換えたプログラムだと,すべての配列に同じものが入ってしまいました...
その原因がわからなくて(;_;)
0009デフォルトの名無しさんNGNG
>>1
お前はまずCの再初歩からやり直せ。
char*が何かわかってるのか?
0010あきらNGNG
charへのポインタでしょ??
0011高校生NGNG
メンドウだがnew char[strlen...]したオブジェクトを全部解放しろ。
メンドウだがc++の文字列はcharの配列だ!一文字ずつコピーしろ。
for (i = 0; i < 6; i++)
 a[i] = "hello"[i];
メンドウだがcから勉強しろ。
0012デフォルトの名無しさんNGNG
じゃぁ
> a[i] = s;
これは何だ?
0013mikagetanNGNG
voidの本で勉強しろや>>1
0014デフォルトの名無しさんNGNG
>>11
さすが高校生だな(w
00156NGNG
char* a[3];
char s[4] = "aaa";
a[0] = s;

これが正解だな。
昔悩んで納得していたんだが、すっかり忘れてしまってる。
確か配列とポインタの違いが関係あるような。
0016攻防NGNG
char s[3][256];
cout<<"a["<<i<<"] = ";
cin>>s[i];

a[i] = s[i];  
strcpy(a[i], s[i]);

これで取り合えずよし、と。
0017デフォルトの名無しさんNGNG
>>15
1の意図とは違う、っていうか1と同じ事言ってどうするよ。
0018高校生NGNG
メンドウだがstrcpyのライブラリコードを確認してみろ!
strcpy(dest, src)
 char *dest, *src;
{
 while (*dest++ = *src++);
}
みたいな感じだろ。分からんかったら配列で書き直してみろ。
00196NGNG
あら、よく見たら>>1hはchar*型のインスタンスを動的生成してるんだね。
そんなのあり!??
0020デフォルトの名無しさんNGNG
>>19
開放し忘れてることを除けばあり。
しかし糞スレの割りに続くな、10逝かないと思ったんだが。
00216NGNG
>>20
ああ、そういえば全然普通のことかなあ。
STL使ってる弊害か、かなーり忘れてる。ヤバー。
0022あきらNGNG
>>12さん
a[i]="abcde";
はオッケーなのに,
a[i]=s;
がダメなのはどうしてでしょうか??

0023デフォルトの名無しさんNGNG
> a[i]="abcde";
> はオッケーなのに,

誰がんな事逝ったボケ!
0024あきらNGNG
>>23
char* a = "abc";
a = "abcde";
はオッケーですよね?
0025あきらNGNG
>>6
インスタンスってなんですか?
馬鹿らしい質問かもしれませんが...
0026デフォルトの名無しさんNGNG
>>24
char* a = "abc";
char* b = "abc";
b[1] = 'B';
puts(a);
コンパイラによっては大問題。
0027高校生NGNG
これで理解できなければアキラメナ。。。

char buf[] = {'a', 'b', 'c', 0};
char *p[3];

p[0] = buf;
buf[1] = 'h';
p[1] = buf;
buf[2] = 'o';
p[2] = buf;

printf("お前は%sじゃ\n", p[0]);
00286NGNG
char** a = new char*[3];
char* s = "01234";
a[0] = new char[strlen(s) + 1];
strcpy(a[0], s);
delete[] a[0];
delete[] a;

これでコンパイル通るなぁ。
で>>1、「 //「ここ」 」でエラったんだけど・・
まさかねぇ
0029あきらNGNG
>>6、「 //「ここ」 」でエラったんだけど・・
ここでエラーしたのではなくて
参考書のとおりのプログラム(上のやつ)だと,走るんだけど
自分で「これじゃダメかな?」って
a[i]=s;
と書き換えたらダメだったんです...

00306NGNG
>>29
ああ失礼。
俺狂ってるなあ、さっきから。寝よう。
0031高校生NGNG
>>あきら
詰まらんからageるな!>>27を確認して実行してみろ。
0032デフォルトの名無しさんNGNG
まず1は
a[i]=s;
に具体的にどんな効果を期待したのか詳細に説明してください。
なぜそうなると思うのかも必ず書いてください。
0033ニュートラル ◆w24VbftE NGNG
>>1
変数 a は char へのポインタ のポインタです。
変数 s は char の配列、つまり文字列自体です。これは固定的に確保されているので、「s のアドレスは一定」です(これ重要)
a[i] は char へのポインタです。( a の1から3番目の要素は char へのポインタなので)

a[i] = new char[strlen(s) + 1]; で、s の長さに応じたメモリを確保し、
a[i] がそこを指すようにしています。
(>>1のコードではこのメモリを開放し忘れています。)
strcpy(a[i], s); で a[i] の指すアドレスへ s の指すアドレスから strcpy
しています。
これを a[i] = s; に置き換えるとすると、
s をポインタとしてみた時の値は一定なので、a[0] から a[2] までに全て
同じ値が入ります。
結果として どれを表示しても同じ文字列が表示されます。
( a[0] から a[2] が指しているのは全て s という配列の「中身」です。)

これが理解できないという事はポインタ、アドレス等について
( >1 のコードを見る限りメモリの確保と開放についても)
理解できていないという事だと思いますので、そこらへんを重点的に勉強しましょう。
コンピュータの動く仕組みを漠然とでもいいのでイメージできるようになると
大分理解できるようになると思いますので頑張りましょう。
0034デフォルトの名無しさんNGNG
>>33
ついでにforブロック内のsをその外の変数a[i]に代入する危険性も指摘やってください。
0035たぶんNGNG
>> char** a = new char*[3];

で何がどうnewされたのか分かってないんじゃないすか?
0036高校生NGNG
>>33
strcpyやnew char[...みたいなブラックボックスな
説明じゃぁ>>1には理解できんと思う。。。
0037あきらNGNG
>>31
27の実行結果は読めばわかります.

>>32
参考書(プログラミング講義C++)で
char* a = "abc";
a = "12345";
がオッケーらしいので,char* の配列a[i]の各要素にも
a[i]="123";
でいけると思いました.それで,たとえば
s[256]="123";
a[i]=s;
も大丈夫だと...
003832NGNG
>>37
何の説明にもなっていません。
> char* a = "abc";
> a = "12345";
 :
> s[256]="123";
> a[i]=s;
これがどう動いているかあなたはまったく理解していません。
0039高校生NGNG
>>37

>>1と>>27は、同じ現象が起こっていることに気づけよ。。。
>>27のp[0]、p[1]、p[2]の内容がどうなっているのか
printfしてみたのか?
00406NGNG
はっはー、やっとスレの主旨がわかったゾ。うれぴい。
>>1が何が疑問なのか全然わからなかったよ。
別に a[i]=s; は間違いじゃないよ。コンパイルが通るんだから間違ってないじゃん。
期待通りの動作もするし。そういうことだよ。
寝よ。
0041デフォルトの名無しさんNGNG
>>39
結果だけ見せても理由はわからん。
0042ニュートラル ◆w24VbftE NGNG
>>34
インデント無かったから気づかなかった…。メチャメチャ危険だったね。

>>1
君に C++ は危険すぎる。
将来的に C++ が使いたいのだとしてもコンピュータの仕組みを理解する為に C を、
オブジェクト指向を理解する為に Java か C# を
それぞれ別々に勉強する事をオススメする。
0043デフォルトの名無しさんNGNG
>>40
そうなんだよねぇ。
>>1のコードが、まともなプログラマがああなることを意図して書いたなら何の問題も無いプログラムなんだけど。
1はそのプログラムが違う動作をすることを期待してるんだよねぇ。
0044デフォルトの名無しさんNGNG
>>1お前のコードはこれより意味がわからん。

int i=0,*p=&i;
*p = ++i;
printf("%d",*p);
0045デフォルトの名無しさんNGNG
>>44
それって未定義だよね?
0046あきらNGNG
>>33さん
>>変数 s は char の配列、つまり文字列自体です。これは固定的に確保されているので、「s のアドレスは一定」です(これ重要)

>>s をポインタとしてみた時の値は一定なので、a[0] から a[2] までに全て
同じ値が入ります。

ここの理解があいまいでした.
僕が一番あいまいなまま気になってた箇所を丁寧に指摘してもらって,ほんと有難いです.
まだまだ勉強不足ですが,がんばりたいです.

あと,開放に関してですが
delete[] a[i];
はオリジナルコードの下のほうにあったので,コピペし忘れてました.
自分の疑問点ばかり気にしててすみませんでしたm(_ _)m
0047デフォルトの名無しさんNGNG
>>45
44は未定義じゃ無いだろ。
代入が意味無いだけで。
0048デフォルトの名無しさんNGNG
終了したようですがついでに

char str[256]="hoge";
では配列が"hoge"で初期化されますが、その後はstrは定数になります。
配列の先頭アドレスなんだからあたりまえですね。だからその後に
str="hoge2";
とはできないんです。
宣言部での=は初期化であり、それ以外では代入だということに注意してください。
0049高校生NGNG
>>46
まずはK&Rでも読んでCのメモリへの透過性の高さを把握してから
C++へ移行することを勧める。今の君では、複雑なC++を学習する
のは無理だ。Cでなく、なぜC++からはじめるのか、それを訊きたい。
0050デフォルトの名無しさんNGNG
>>49
な、なんかカコイイ・・・( *´Д`)
0051あきらNGNG
>>高校生さん
p[i](i=0,1,2)をcoutさせました.
33さんの説明と高校生さんのコードの結果で
勘違いしてた箇所がはっきりしました.
2chにカキコしてよかった!!
0052ニュートラル ◆w24VbftE NGNG
>>50
 >>42 で僕も同じ事言ってるのに…。
0053祭りがNGNG
祭りが終わってしまったわ。。。
はかない深夜スレだったね。
0054デフォルトの名無しさんNGNG
>>51
cout好き?漏れはほとんど使わないんだけど。
なんかC/C++らしくない気がするんだよねぇ。
Perlっぽい雰囲気がする。
0055デフォルトの名無しさんNGNG
>1はPerlあたりでCGIマンセーでいいだろう。
0056あきらNGNG
>>49
本当に高校生??
C++が世の中に出てしばらく経った後に
プログラムの勉強を始めた人って,
C++から始める人もいると思うんだけど
よくないのかな?
そういう参考書もでてて,僕もC++から入ったんだけど...
0057デフォルトの名無しさんNGNG
>>56
漏れはC++(つーかVC++)から始めようと思ってたけど、
さすがに意味不明だったから独習Cを1日ほど読んでんで独習C++で2日ほどかかって大体できるようになったかなぁ。
当時はSTLは理解できなかったけど。
0058>Akira!さんへNGNG
失礼ですがお幾つでいらっしゃりますか?
0059ニュートラル ◆w24VbftE NGNG
>>1
ちなみに僕もリアル工房の時、C 理解しないまま C++ に突入しようとしたけど、
木端微塵に敗れ去って、C と x86 アセンブラ(こっちはほんのさわりだけ)
からやり直したよ。
その後 Java で OO を理解して、やっと最近 C++ が理解「できそうになってきた」
いきなり C++ やろうとしても、機能に押しつぶされるのと、謎のバグの嵐の前に
叩きのめされるのがオチだと思うので、素直に基本から極めた方がいいよ。
0060あきらNGNG
>>58
23歳,大学4年です
0061デフォルトの名無しさんNGNG
>>59
アセンブラやっといたほうがいいと思う?
漏れもやろうやろうと思ってるんだけど・・・なかなか。
0062ニュートラル ◆w24VbftE NGNG
>>1
同い年じゃん(^^
僕より高学歴だけどなー(鬱
0063あきらNGNG
>>59
そうだったんですか.
僕は卒研の数値計算でプログラムを始めたので
関数や算術系はともかく,文字列の操作などは全然で...
0064デフォルトの名無しさんNGNG
もれ二十歳だけどこのペースで逝くと・・・(鬱氏
0065高校生NGNG
>>63
だったら多倍長精度の計算で配列使いまくったろ?
多倍長精度同士の積をTFFでゴマカスとかやらされたろ。。。
0066ニュートラル ◆w24VbftE NGNG
>>61
C で既にバリバリに組めるなら…それほど必要ないのかも。
僕の場合はアセンブラ触ったおかげで
「プログラムがどうやって動いているか」が理解できたから
自分の書いたコードのどこがおかしいのか、とかは
よくわかるようになったよ。

ポインタ、アドレス、スタック等々のしくみみたいなモノね。
最近やっとマルチスレッドに手をだしたので、スタックの仕組みを
理解してた事は凄く役に立ったよ。
0067デフォルトの名無しさんNGNG
ム板の不思議。
何故深夜はとてもマターリしてるのか。
0068デフォルトの名無しさんNGNG
>>67
たぶん昼間マターリできないからだと思われ
0069デフォルトの名無しさんNGNG
このスレも普通なら「スレ立てるまでも無い・・・」に逝けって言われるのにな。
なぜかそれなりにレスついたし。
0070高校生NGNG
>>65
誤:TFF
正:FFT (Fast Fourier Transform)
0071ニュートラル ◆w24VbftE NGNG
>>69
そうだよね、いつもなら「クソスレ立てんなゴルァ」って言われてる。
でも、深夜だからだけじゃなくて、>>1 が微妙にいいセンス醸し出してたのかも。
僕は >>1 見た時、ダンボール箱の中でニャアニャア鳴いてる仔猫を見つけたような感覚を感じたよ(W
0072あきらNGNG
>>65
行列計算で2次元配列にはお世話になったけど
>>TFFでゴマカスとかやらされたろ。。。
こういうのはなかったよ(^^;
超大型行列なので,いかにメモリ&時間を節約するか・・・でした(笑)
>>67〜69
スレ立てた本人がレスしてるから・・・?!
0073デフォルトの名無しさんNGNG
>>71あなたは母性本能満タンです。
ママンになれます。
0074あきらNGNG
>>71
(((^^;けど,勉強になったから(笑)
僕,普段はここにカキコしないんだけど(専門的過ぎてついていけない;;;)
来てよかった!
普段は音楽系の板にいるよ(^^;
0075高校生NGNG
>>72
すべての場合に効率よく行列計算できるわけじゃなかろう。。。
詳細は?
0076ニュートラル ◆w24VbftE NGNG
>>73
ママンなのか?男なのに(;W;

>>74
頑張って勉強してね。でもこれから単発質問は専用スレにね。
僕はこの板によくいるので(このコテハンはこないだ使い始めたばっかりだけど)
0077あきらNGNG
>>72
帯行列だったり対称疎行列だったりだから,工夫のしがいがあるって言うか(笑)
2000*2000くらいかな.
ほんとはOctaveとかでするべきなんだろうけど,C++はじめたくて(^^;
行列の代数方程式までC(++)で書いて,それをOctaveで計算できたら最高なんだけど・・・難しいよね??
0078あきらNGNG
>>ニュートラルさん
単発質問の専用スレってどれなんでしょうか?
0079デフォルトの名無しさんNGNG
漏れにはサパーリわからん(;´Д`)>FFT&行列
ちと遊びすぎたかも・・・。
0080ニュートラル ◆w24VbftE NGNG
汎用的なやつは↓。連番が16進な事が最近発覚した
***すれ立てるまでもない質問はここで 第A刷***
http://pc.2ch.net/test/read.cgi/tech/1012536901/

そのほかにも、言語、環境なんかで色々立ってるよ。
今回のは C++相談室 がよかったかも
http://pc.2ch.net/test/read.cgi/tech/1009071535/
0081あきらNGNG
>>80
ありがとうございました.
かなり遅くまで起きてるけど,明日は仕事ですか?
0082ニュートラル ◆w24VbftE NGNG
>>81
あまりに過酷な労働環境だったので去年末に会社辞めたのさ(W
今は長い冬休み&再就職活動中。
第二新卒な Java プログラマーは引く手あまたみたいで、
この不景気でもポッと受けに行った会社の面接の終わりに
「いいお返事ができると思います」とか言われちゃうので
今のうちに久々の長い休暇を楽しんでる所だったり(W
0083あきらNGNG
やっぱり職としてるからか,知識というか実戦的なモノをもってるなぁって感じました(^^;
0084ニュートラル ◆w24VbftE NGNG
>>83
プログラマーっていう職業になると、わかれるからねぇ…。
ちゃんとわかってる人間と、わからないままゴミコード書き連ねる人間に。

僕の場合は学生のうちに基礎が固まってたけど、
やっぱり社会人になると、何かが違うかも。
技術(僕の場合はプログラミング)以外の事、社会人としてのマナーとか
そういうものが、技術に結びついてくるというか、
社会に出る事で、人間的に大きくなるのかも。
0085あきらNGNG
>>84
なるほど...僕も早く”社会人”として世の中に出たいです.
もうすぐだけど,それまでに少しでも知っておきたくて今勉強してます.
会社に入ってからでも十分〜って人事の人とかは言うけど・・・?だし.
0086デフォルトの名無しさんNGNG
Cやれって言わなくても、
STL使わせてポインタを隠蔽すれば
いきなりC++でも全然問題ないと思う。
漏れはいちおうCは分かるけど、ポインタ嫌いだし、
今はSTLばっかでポインタ配列なんかほとんど使わない。(w
0087ニュートラル ◆w24VbftE NGNG
>>85
常に勉強を怠らなければ、会社入ってからでも十分だけど、
僕の後輩を見てて思ったのは
「入ってきた時点で何も知らないやつは、入ってからも勉強しない」
って事かな?会社入る前に「少しでも知っておきたい」っていう気持ちがあるなら多分大丈夫。

>>86
僕もポインタは好きじゃないけどね、C++ 出来ますって言うには
他人が書いたコードの保守もできなきゃいけないし。
そうすると「お前 C++ 知らないだろ!」っていう C バリバリなコードに
直面する機会は満載じゃない?
0088デフォルトの名無しさんNGNG
>>87
あんたイイこと言うじゃん。激しく同意
0089あきらNGNG
>>87さん
結局徹夜でずっと大学にいます(^^;
昨夜教えてもらったことを基にして,
現在複素数の2次元配列を動的生成させることができるようになり,
卒研のために書いたコードを改良できそうです♪
これでもっとメモリを節約できるかなぁ.

0090ニュートラル ◆w24VbftE NGNG
>>88
いやいや、まだまだ未熟者です^^。

>>89
大変な事も色々あるかも知れないけど頑張れ〜!
0091デフォルトの名無しさんNGNG
>>6
俺もポインタはいらないと思う。
昨今のプログラム言語のポインタ排除の流れは
必然であるとさえ思える。

>>48
遅レスですまんがそれは違うと思う。
char str[5] = "hoge";
とchar配列の宣言がリテラル文字列で初期化できるのは
あくまで文字列に限った例外であると思う。
strは定数にはならない。
str[0] = 'a';
str[1] = 'h';
str[2] = 'o';
と記述すれば変更出来る。
ただ例外である"aho"が使えないだけで。
009291NGNG
>>6 → >>86 の間違いでした。
0093デフォルトの名無しさんNGNG
strが定数なのとstr[n]が定数なのと、行き違ってるのかな?
009491NGNG
すまん、説明の意味を取り違ってしまった。
上のレスなしね。
0095デフォルトの名無しさんNGNG
ホントに高校生だったらヤな高校生だなぁ(^^;
最初にTTFと書いてる所が高校生らしさを出してるのかもしれん
0096原田です。NGNG
あきらです
0097ハイ皆さん声をそろえて!NGNG
三瓶です。
0098デフォルトの名無しさんNGNG
辻ちゃんです。
0099デフォルトの名無しさんNGNG
加護ちゃんです。
0100デフォルトの名無しさんNGNG
名前はまだない。
0101デフォルトの名無しさんNGNG
ム板住人が知ってる娘メンバーなんてその程度のもんか。
あと、なっちくらいか。
0102デフォルトの名無しさんNGNG
>>96
ホストマンですっ
ふぅう〜っ
0103デフォルトの名無しさんNGNG
>>101
市井さやかでした(過去形)
0104デフォルトの名無しさんNGNG





















透明人間がこのスレに興味をもったようです。
■ このスレッドは過去ログ倉庫に格納されています